From 6840bfd101db1fc4674b1724fdd126855d026e41 Mon Sep 17 00:00:00 2001 From: Quentin MELOTTE Date: Thu, 2 Jul 2026 15:06:12 +0200 Subject: [PATCH 1/6] Check not finished --- CodeExamples/Add-With-Specialization.aarch64 | Bin 0 -> 39832 bytes .../Add-With-Specialization.aarch64.c | 976 +++++++ CodeExamples/Add-With-Specialization.power | Bin 0 -> 78168 bytes CodeExamples/Add-With-Specialization.power.c | 774 ++++++ CodeExamples/Add-With-Specialization.riscv | Bin 0 -> 29136 bytes CodeExamples/Add-With-Specialization.riscv.c | 667 +++++ CodeExamples/Add-With-Transprecision.aarch64 | Bin 0 -> 43928 bytes .../Add-With-Transprecision.aarch64.c | 1101 ++++++++ CodeExamples/Add-With-Transprecision.power | Bin 0 -> 78288 bytes CodeExamples/Add-With-Transprecision.power.c | 850 ++++++ CodeExamples/Add-With-Transprecision.riscv | Bin 0 -> 29136 bytes CodeExamples/Add-With-Transprecision.riscv.c | 722 ++++++ CodeExamples/Array-Ld-flt.aarch64 | Bin 0 -> 48048 bytes CodeExamples/Array-Ld-flt.aarch64.c | 1233 +++++++++ CodeExamples/Array-Ld-flt.power | Bin 0 -> 78424 bytes CodeExamples/Array-Ld-flt.power.c | 895 +++++++ CodeExamples/Array-Ld-flt.riscv | Bin 0 -> 33296 bytes CodeExamples/Array-Ld-flt.riscv.c | 815 ++++++ CodeExamples/Array-Ld.aarch64 | Bin 0 -> 43952 bytes CodeExamples/Array-Ld.aarch64.c | 1178 +++++++++ CodeExamples/Array-Ld.power | Bin 0 -> 78192 bytes CodeExamples/Array-Ld.power.c | 882 +++++++ CodeExamples/Array-Ld.riscv | Bin 0 -> 33248 bytes CodeExamples/Array-Ld.riscv.c | 795 ++++++ .../Array-Mult-Specialization.aarch64 | Bin 0 -> 48416 bytes .../Array-Mult-Specialization.aarch64.c | 1327 ++++++++++ CodeExamples/Array-Mult-Specialization.power | Bin 0 -> 78720 bytes .../Array-Mult-Specialization.power.c | 1052 ++++++++ CodeExamples/Array-Mult-Specialization.riscv | Bin 0 -> 37596 bytes .../Array-Mult-Specialization.riscv.c | 918 +++++++ CodeExamples/Array-St-flt.aarch64 | Bin 0 -> 48112 bytes CodeExamples/Array-St-flt.aarch64.c | 1233 +++++++++ CodeExamples/Array-St-flt.power | Bin 0 -> 78544 bytes CodeExamples/Array-St-flt.power.c | 909 +++++++ CodeExamples/Array-St-flt.riscv | Bin 0 -> 33332 bytes CodeExamples/Array-St-flt.riscv.c | 822 ++++++ CodeExamples/Array-St.aarch64 | Bin 0 -> 48056 bytes CodeExamples/Array-St.aarch64.c | 1205 +++++++++ CodeExamples/Array-St.power | Bin 0 -> 78304 bytes CodeExamples/Array-St.power.c | 909 +++++++ CodeExamples/Array-St.riscv | Bin 0 -> 33256 bytes CodeExamples/Array-St.riscv.c | 822 ++++++ CodeExamples/Array-Sum-2D.aarch64 | Bin 0 -> 52312 bytes CodeExamples/Array-Sum-2D.aarch64.c | 1385 ++++++++++ CodeExamples/Array-Sum-2D.power | Bin 0 -> 78352 bytes CodeExamples/Array-Sum-2D.power.c | 1110 ++++++++ CodeExamples/Array-Sum-2D.riscv | Bin 0 -> 41540 bytes CodeExamples/Array-Sum-2D.riscv.c | 971 +++++++ CodeExamples/CelciusFarenheit.aarch64 | Bin 0 -> 48128 bytes CodeExamples/CelciusFarenheit.aarch64.c | 1306 ++++++++++ CodeExamples/CelciusFarenheit.power | Bin 0 -> 78272 bytes CodeExamples/CelciusFarenheit.power.c | 986 +++++++ CodeExamples/CelciusFarenheit.riscv | Bin 0 -> 41504 bytes CodeExamples/CelciusFarenheit.riscv.c | 902 +++++++ CodeExamples/Constants-Operations.aarch64 | Bin 0 -> 52312 bytes CodeExamples/Constants-Operations.aarch64.c | 1387 ++++++++++ CodeExamples/Constants-Operations.power | Bin 0 -> 78360 bytes CodeExamples/Constants-Operations.power.c | 1067 ++++++++ CodeExamples/Constants-Operations.riscv | Bin 0 -> 53860 bytes CodeExamples/Constants-Operations.riscv.c | 1025 ++++++++ CodeExamples/If-in-Loop.aarch64 | Bin 0 -> 52344 bytes CodeExamples/If-in-Loop.aarch64.c | 1471 +++++++++++ CodeExamples/If-in-Loop.power | Bin 0 -> 78384 bytes CodeExamples/If-in-Loop.power.c | 1172 +++++++++ CodeExamples/If-in-Loop.riscv | Bin 0 -> 41564 bytes CodeExamples/If-in-Loop.riscv.c | 1019 ++++++++ CodeExamples/If.aarch64 | Bin 0 -> 44024 bytes CodeExamples/If.aarch64.c | 1117 ++++++++ CodeExamples/If.power | Bin 0 -> 78264 bytes CodeExamples/If.power.c | 936 +++++++ CodeExamples/If.riscv | Bin 0 -> 33272 bytes CodeExamples/If.riscv.c | 782 ++++++ CodeExamples/Loop-in-If.aarch64 | Bin 0 -> 52312 bytes CodeExamples/Loop-in-If.aarch64.c | 1439 ++++++++++ CodeExamples/Loop-in-If.power | Bin 0 -> 78352 bytes CodeExamples/Loop-in-If.power.c | 1164 +++++++++ CodeExamples/Loop-in-If.riscv | Bin 0 -> 41540 bytes CodeExamples/Loop-in-If.riscv.c | 1024 ++++++++ CodeExamples/Loop.aarch64 | Bin 0 -> 44024 bytes CodeExamples/Loop.aarch64.c | 1125 ++++++++ CodeExamples/Loop.power | Bin 0 -> 78264 bytes CodeExamples/Loop.power.c | 944 +++++++ CodeExamples/Loop.riscv | Bin 0 -> 33276 bytes CodeExamples/Loop.riscv.c | 790 ++++++ CodeExamples/LoopNest.aarch64 | Bin 0 -> 52232 bytes CodeExamples/LoopNest.aarch64.c | 1438 ++++++++++ CodeExamples/LoopNest.power | Bin 0 -> 78376 bytes CodeExamples/LoopNest.power.c | 1257 +++++++++ CodeExamples/LoopNest.riscv | Bin 0 -> 49712 bytes CodeExamples/LoopNest.riscv.c | 1078 ++++++++ CodeExamples/Mult-With-Specialization.aarch64 | Bin 0 -> 43968 bytes .../Mult-With-Specialization.aarch64.c | 1138 ++++++++ CodeExamples/Mult-With-Specialization.power | Bin 0 -> 78208 bytes CodeExamples/Mult-With-Specialization.power.c | 842 ++++++ CodeExamples/Mult-With-Specialization.riscv | Bin 0 -> 29172 bytes CodeExamples/Mult-With-Specialization.riscv.c | 755 ++++++ CodeExamples/Multiple-flt.aarch64 | Bin 0 -> 52288 bytes CodeExamples/Multiple-flt.aarch64.c | 1547 +++++++++++ CodeExamples/Multiple-flt.power | Bin 0 -> 78456 bytes CodeExamples/Multiple-flt.power.c | 1157 +++++++++ CodeExamples/Multiple-flt.riscv | Bin 0 -> 57932 bytes CodeExamples/Multiple-flt.riscv.c | 1087 ++++++++ CodeExamples/Multiple-int.aarch64 | Bin 0 -> 52288 bytes CodeExamples/Multiple-int.aarch64.c | 1406 ++++++++++ CodeExamples/Multiple-int.power | Bin 0 -> 78336 bytes CodeExamples/Multiple-int.power.c | 1086 ++++++++ CodeExamples/Multiple-int.riscv | Bin 0 -> 53836 bytes CodeExamples/Multiple-int.riscv.c | 1044 ++++++++ CodeExamples/RegressionSingleOp.py | 30 +- ...ess-mul-int-008-128-aarch64+riscv+power.hl | 46 + .../Tests/Test-Value-sub-flt-064-001-+.hl | 46 + .../__pycache__/CCode.cpython-312.pyc | Bin 0 -> 10296 bytes CodeExamples/regression-single-op-aarch64.csv | 2304 +++++++++++++++++ Demos/Makefile | 14 + .../Newton.c | 925 +++++++ .../Newton.riscv | Bin 0 -> 65000 bytes Demos/Stencil/Stencil.aarch64 | Bin 0 -> 86152 bytes Demos/Stencil/Stencil.aarch64.c | 2275 ++++++++++++++++ Demos/Stencil/Stencil.power | Bin 0 -> 145696 bytes Demos/Stencil/Stencil.power.c | 1955 ++++++++++++++ Demos/Stencil/Stencil.riscv | Bin 0 -> 171700 bytes Demos/Stencil/Stencil.riscv.c | 1892 ++++++++++++++ Demos/VectorMatrix/VectorMatrix.aarch64 | Bin 0 -> 63912 bytes Demos/VectorMatrix/VectorMatrix.aarch64.c | 1923 ++++++++++++++ Demos/VectorMatrix/VectorMatrix.power | Bin 0 -> 80624 bytes Demos/VectorMatrix/VectorMatrix.power.c | 1457 +++++++++++ Demos/VectorMatrix/VectorMatrix.riscv | Bin 0 -> 62544 bytes Demos/VectorMatrix/VectorMatrix.riscv.c | 1230 +++++++++ HybroGen/IsaDescription.interp | 58 + HybroGen/IsaDescription.tokens | 22 + HybroGen/IsaDescriptionLexer.interp | 59 + HybroGen/IsaDescriptionLexer.py | 92 + HybroGen/IsaDescriptionLexer.tokens | 22 + HybroGen/IsaDescriptionListener.py | 183 ++ HybroGen/IsaDescriptionParser.py | 1179 +++++++++ HybroGen/RegisterDescription.interp | 50 + HybroGen/RegisterDescription.tokens | 16 + HybroGen/RegisterDescriptionLexer.interp | 53 + HybroGen/RegisterDescriptionLexer.py | 92 + HybroGen/RegisterDescriptionLexer.tokens | 16 + HybroGen/RegisterDescriptionListener.py | 147 ++ HybroGen/RegisterDescriptionParser.py | 891 +++++++ HybroGen/__pycache__/Counter.cpython-312.pyc | Bin 0 -> 1673 bytes .../GenGeneratorFromDb.cpython-312.pyc | Bin 0 -> 18476 bytes HybroGen/__pycache__/Insn.cpython-312.pyc | Bin 0 -> 8549 bytes HybroGen/__pycache__/IsaDb.cpython-312.pyc | Bin 0 -> 3882 bytes .../IsaDescriptionLexer.cpython-312.pyc | Bin 0 -> 4975 bytes .../IsaDescriptionListener.cpython-312.pyc | Bin 0 -> 7640 bytes .../IsaDescriptionParser.cpython-312.pyc | Bin 0 -> 64046 bytes HybroGen/__pycache__/PGen.cpython-312.pyc | Bin 0 -> 3465 bytes HybroGen/__pycache__/ProxyDb.cpython-312.pyc | Bin 0 -> 15935 bytes HybroGen/__pycache__/Register.cpython-312.pyc | Bin 0 -> 3665 bytes .../RegisterDescriptionLexer.cpython-312.pyc | Bin 0 -> 5102 bytes ...egisterDescriptionListener.cpython-312.pyc | Bin 0 -> 6685 bytes .../RegisterDescriptionParser.cpython-312.pyc | Bin 0 -> 50224 bytes HybroGen/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 146 bytes HybroLang/.antlr/HybroLang.interp | 125 + HybroLang/.antlr/HybroLang.tokens | 84 + HybroLang/.antlr/HybroLangBaseListener.java | 327 +++ HybroLang/.antlr/HybroLangLexer.interp | 162 ++ HybroLang/.antlr/HybroLangLexer.java | 329 +++ HybroLang/.antlr/HybroLangLexer.tokens | 84 + HybroLang/.antlr/HybroLangListener.java | 255 ++ HybroLang/.antlr/HybroLangParser.java | 1680 ++++++++++++ HybroLang/HybroLang.interp | 125 + HybroLang/HybroLang.tokens | 84 + HybroLang/HybroLangLexer.interp | 162 ++ HybroLang/HybroLangLexer.py | 240 ++ HybroLang/HybroLangLexer.tokens | 84 + HybroLang/HybroLangParser.py | 1602 ++++++++++++ .../H2Aarch64Rewrite.cpython-312.pyc | Bin 0 -> 4184 bytes .../H2CodeGeneration.cpython-312.pyc | Bin 0 -> 15344 bytes .../H2CxRAMRewrite.cpython-312.pyc | Bin 0 -> 19217 bytes HybroLang/__pycache__/H2Debug.cpython-312.pyc | Bin 0 -> 3339 bytes .../__pycache__/H2GenGen.cpython-312.pyc | Bin 0 -> 7504 bytes HybroLang/__pycache__/H2IR2.cpython-312.pyc | Bin 0 -> 9987 bytes .../__pycache__/H2LabelTable.cpython-312.pyc | Bin 0 -> 2887 bytes .../__pycache__/H2MovOptimize.cpython-312.pyc | Bin 0 -> 3907 bytes HybroLang/__pycache__/H2Node.cpython-312.pyc | Bin 0 -> 16155 bytes .../__pycache__/H2NodeType.cpython-312.pyc | Bin 0 -> 1069 bytes .../H2PowerRewrite.cpython-312.pyc | Bin 0 -> 2865 bytes .../__pycache__/H2RegAllocTmp.cpython-312.pyc | Bin 0 -> 4591 bytes .../__pycache__/H2RegCSI.cpython-312.pyc | Bin 0 -> 5373 bytes .../H2RegisterBank.cpython-312.pyc | Bin 0 -> 8261 bytes .../H2RiscvRewrite.cpython-312.pyc | Bin 0 -> 2632 bytes .../__pycache__/H2SymbolTable.cpython-312.pyc | Bin 0 -> 4311 bytes .../H2TransformToMac.cpython-312.pyc | Bin 0 -> 2645 bytes HybroLang/__pycache__/H2Type.cpython-312.pyc | Bin 0 -> 1606 bytes .../H2WindowRewrite.cpython-312.pyc | Bin 0 -> 6098 bytes .../HybroLangLexer.cpython-312.pyc | Bin 0 -> 13941 bytes .../HybroLangParser.cpython-312.pyc | Bin 0 -> 87146 bytes .../HybroLangVisitor.cpython-312.pyc | Bin 0 -> 6012 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 147 bytes Makefile | 47 +- __pycache__/H2Utils.cpython-312.pyc | Bin 0 -> 394 bytes __pycache__/SwConfig.cpython-312.pyc | Bin 0 -> 2594 bytes 196 files changed, 79384 insertions(+), 25 deletions(-) create mode 100755 CodeExamples/Add-With-Specialization.aarch64 create mode 100644 CodeExamples/Add-With-Specialization.aarch64.c create mode 100755 CodeExamples/Add-With-Specialization.power create mode 100644 CodeExamples/Add-With-Specialization.power.c create mode 100755 CodeExamples/Add-With-Specialization.riscv create mode 100644 CodeExamples/Add-With-Specialization.riscv.c create mode 100755 CodeExamples/Add-With-Transprecision.aarch64 create mode 100644 CodeExamples/Add-With-Transprecision.aarch64.c create mode 100755 CodeExamples/Add-With-Transprecision.power create mode 100644 CodeExamples/Add-With-Transprecision.power.c create mode 100755 CodeExamples/Add-With-Transprecision.riscv create mode 100644 CodeExamples/Add-With-Transprecision.riscv.c create mode 100755 CodeExamples/Array-Ld-flt.aarch64 create mode 100644 CodeExamples/Array-Ld-flt.aarch64.c create mode 100755 CodeExamples/Array-Ld-flt.power create mode 100644 CodeExamples/Array-Ld-flt.power.c create mode 100755 CodeExamples/Array-Ld-flt.riscv create mode 100644 CodeExamples/Array-Ld-flt.riscv.c create mode 100755 CodeExamples/Array-Ld.aarch64 create mode 100644 CodeExamples/Array-Ld.aarch64.c create mode 100755 CodeExamples/Array-Ld.power create mode 100644 CodeExamples/Array-Ld.power.c create mode 100755 CodeExamples/Array-Ld.riscv create mode 100644 CodeExamples/Array-Ld.riscv.c create mode 100755 CodeExamples/Array-Mult-Specialization.aarch64 create mode 100644 CodeExamples/Array-Mult-Specialization.aarch64.c create mode 100755 CodeExamples/Array-Mult-Specialization.power create mode 100644 CodeExamples/Array-Mult-Specialization.power.c create mode 100755 CodeExamples/Array-Mult-Specialization.riscv create mode 100644 CodeExamples/Array-Mult-Specialization.riscv.c create mode 100755 CodeExamples/Array-St-flt.aarch64 create mode 100644 CodeExamples/Array-St-flt.aarch64.c create mode 100755 CodeExamples/Array-St-flt.power create mode 100644 CodeExamples/Array-St-flt.power.c create mode 100755 CodeExamples/Array-St-flt.riscv create mode 100644 CodeExamples/Array-St-flt.riscv.c create mode 100755 CodeExamples/Array-St.aarch64 create mode 100644 CodeExamples/Array-St.aarch64.c create mode 100755 CodeExamples/Array-St.power create mode 100644 CodeExamples/Array-St.power.c create mode 100755 CodeExamples/Array-St.riscv create mode 100644 CodeExamples/Array-St.riscv.c create mode 100755 CodeExamples/Array-Sum-2D.aarch64 create mode 100644 CodeExamples/Array-Sum-2D.aarch64.c create mode 100755 CodeExamples/Array-Sum-2D.power create mode 100644 CodeExamples/Array-Sum-2D.power.c create mode 100755 CodeExamples/Array-Sum-2D.riscv create mode 100644 CodeExamples/Array-Sum-2D.riscv.c create mode 100755 CodeExamples/CelciusFarenheit.aarch64 create mode 100644 CodeExamples/CelciusFarenheit.aarch64.c create mode 100755 CodeExamples/CelciusFarenheit.power create mode 100644 CodeExamples/CelciusFarenheit.power.c create mode 100755 CodeExamples/CelciusFarenheit.riscv create mode 100644 CodeExamples/CelciusFarenheit.riscv.c create mode 100755 CodeExamples/Constants-Operations.aarch64 create mode 100644 CodeExamples/Constants-Operations.aarch64.c create mode 100755 CodeExamples/Constants-Operations.power create mode 100644 CodeExamples/Constants-Operations.power.c create mode 100755 CodeExamples/Constants-Operations.riscv create mode 100644 CodeExamples/Constants-Operations.riscv.c create mode 100755 CodeExamples/If-in-Loop.aarch64 create mode 100644 CodeExamples/If-in-Loop.aarch64.c create mode 100755 CodeExamples/If-in-Loop.power create mode 100644 CodeExamples/If-in-Loop.power.c create mode 100755 CodeExamples/If-in-Loop.riscv create mode 100644 CodeExamples/If-in-Loop.riscv.c create mode 100755 CodeExamples/If.aarch64 create mode 100644 CodeExamples/If.aarch64.c create mode 100755 CodeExamples/If.power create mode 100644 CodeExamples/If.power.c create mode 100755 CodeExamples/If.riscv create mode 100644 CodeExamples/If.riscv.c create mode 100755 CodeExamples/Loop-in-If.aarch64 create mode 100644 CodeExamples/Loop-in-If.aarch64.c create mode 100755 CodeExamples/Loop-in-If.power create mode 100644 CodeExamples/Loop-in-If.power.c create mode 100755 CodeExamples/Loop-in-If.riscv create mode 100644 CodeExamples/Loop-in-If.riscv.c create mode 100755 CodeExamples/Loop.aarch64 create mode 100644 CodeExamples/Loop.aarch64.c create mode 100755 CodeExamples/Loop.power create mode 100644 CodeExamples/Loop.power.c create mode 100755 CodeExamples/Loop.riscv create mode 100644 CodeExamples/Loop.riscv.c create mode 100755 CodeExamples/LoopNest.aarch64 create mode 100644 CodeExamples/LoopNest.aarch64.c create mode 100755 CodeExamples/LoopNest.power create mode 100644 CodeExamples/LoopNest.power.c create mode 100755 CodeExamples/LoopNest.riscv create mode 100644 CodeExamples/LoopNest.riscv.c create mode 100755 CodeExamples/Mult-With-Specialization.aarch64 create mode 100644 CodeExamples/Mult-With-Specialization.aarch64.c create mode 100755 CodeExamples/Mult-With-Specialization.power create mode 100644 CodeExamples/Mult-With-Specialization.power.c create mode 100755 CodeExamples/Mult-With-Specialization.riscv create mode 100644 CodeExamples/Mult-With-Specialization.riscv.c create mode 100755 CodeExamples/Multiple-flt.aarch64 create mode 100644 CodeExamples/Multiple-flt.aarch64.c create mode 100755 CodeExamples/Multiple-flt.power create mode 100644 CodeExamples/Multiple-flt.power.c create mode 100755 CodeExamples/Multiple-flt.riscv create mode 100644 CodeExamples/Multiple-flt.riscv.c create mode 100755 CodeExamples/Multiple-int.aarch64 create mode 100644 CodeExamples/Multiple-int.aarch64.c create mode 100755 CodeExamples/Multiple-int.power create mode 100644 CodeExamples/Multiple-int.power.c create mode 100755 CodeExamples/Multiple-int.riscv create mode 100644 CodeExamples/Multiple-int.riscv.c create mode 100644 CodeExamples/Tests/Test-Address-mul-int-008-128-aarch64+riscv+power.hl create mode 100644 CodeExamples/Tests/Test-Value-sub-flt-064-001-+.hl create mode 100644 CodeExamples/__pycache__/CCode.cpython-312.pyc create mode 100644 CodeExamples/regression-single-op-aarch64.csv create mode 100644 Demos/Newton-SquareRoot-VariablePrecision/Newton.c create mode 100755 Demos/Newton-SquareRoot-VariablePrecision/Newton.riscv create mode 100755 Demos/Stencil/Stencil.aarch64 create mode 100644 Demos/Stencil/Stencil.aarch64.c create mode 100755 Demos/Stencil/Stencil.power create mode 100644 Demos/Stencil/Stencil.power.c create mode 100755 Demos/Stencil/Stencil.riscv create mode 100644 Demos/Stencil/Stencil.riscv.c create mode 100755 Demos/VectorMatrix/VectorMatrix.aarch64 create mode 100644 Demos/VectorMatrix/VectorMatrix.aarch64.c create mode 100755 Demos/VectorMatrix/VectorMatrix.power create mode 100644 Demos/VectorMatrix/VectorMatrix.power.c create mode 100755 Demos/VectorMatrix/VectorMatrix.riscv create mode 100644 Demos/VectorMatrix/VectorMatrix.riscv.c create mode 100644 HybroGen/IsaDescription.interp create mode 100644 HybroGen/IsaDescription.tokens create mode 100644 HybroGen/IsaDescriptionLexer.interp create mode 100644 HybroGen/IsaDescriptionLexer.py create mode 100644 HybroGen/IsaDescriptionLexer.tokens create mode 100644 HybroGen/IsaDescriptionListener.py create mode 100644 HybroGen/IsaDescriptionParser.py create mode 100644 HybroGen/RegisterDescription.interp create mode 100644 HybroGen/RegisterDescription.tokens create mode 100644 HybroGen/RegisterDescriptionLexer.interp create mode 100644 HybroGen/RegisterDescriptionLexer.py create mode 100644 HybroGen/RegisterDescriptionLexer.tokens create mode 100644 HybroGen/RegisterDescriptionListener.py create mode 100644 HybroGen/RegisterDescriptionParser.py create mode 100644 HybroGen/__pycache__/Counter.cpython-312.pyc create mode 100644 HybroGen/__pycache__/GenGeneratorFromDb.cpython-312.pyc create mode 100644 HybroGen/__pycache__/Insn.cpython-312.pyc create mode 100644 HybroGen/__pycache__/IsaDb.cpython-312.pyc create mode 100644 HybroGen/__pycache__/IsaDescriptionLexer.cpython-312.pyc create mode 100644 HybroGen/__pycache__/IsaDescriptionListener.cpython-312.pyc create mode 100644 HybroGen/__pycache__/IsaDescriptionParser.cpython-312.pyc create mode 100644 HybroGen/__pycache__/PGen.cpython-312.pyc create mode 100644 HybroGen/__pycache__/ProxyDb.cpython-312.pyc create mode 100644 HybroGen/__pycache__/Register.cpython-312.pyc create mode 100644 HybroGen/__pycache__/RegisterDescriptionLexer.cpython-312.pyc create mode 100644 HybroGen/__pycache__/RegisterDescriptionListener.cpython-312.pyc create mode 100644 HybroGen/__pycache__/RegisterDescriptionParser.cpython-312.pyc create mode 100644 HybroGen/__pycache__/__init__.cpython-312.pyc create mode 100644 HybroLang/.antlr/HybroLang.interp create mode 100644 HybroLang/.antlr/HybroLang.tokens create mode 100644 HybroLang/.antlr/HybroLangBaseListener.java create mode 100644 HybroLang/.antlr/HybroLangLexer.interp create mode 100644 HybroLang/.antlr/HybroLangLexer.java create mode 100644 HybroLang/.antlr/HybroLangLexer.tokens create mode 100644 HybroLang/.antlr/HybroLangListener.java create mode 100644 HybroLang/.antlr/HybroLangParser.java create mode 100644 HybroLang/HybroLang.interp create mode 100644 HybroLang/HybroLang.tokens create mode 100644 HybroLang/HybroLangLexer.interp create mode 100644 HybroLang/HybroLangLexer.py create mode 100644 HybroLang/HybroLangLexer.tokens create mode 100644 HybroLang/HybroLangParser.py create mode 100644 HybroLang/__pycache__/H2Aarch64Rewrite.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2CodeGeneration.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2CxRAMRewrite.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2Debug.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2GenGen.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2IR2.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2LabelTable.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2MovOptimize.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2Node.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2NodeType.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2PowerRewrite.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2RegAllocTmp.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2RegCSI.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2RegisterBank.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2RiscvRewrite.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2SymbolTable.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2TransformToMac.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2Type.cpython-312.pyc create mode 100644 HybroLang/__pycache__/H2WindowRewrite.cpython-312.pyc create mode 100644 HybroLang/__pycache__/HybroLangLexer.cpython-312.pyc create mode 100644 HybroLang/__pycache__/HybroLangParser.cpython-312.pyc create mode 100644 HybroLang/__pycache__/HybroLangVisitor.cpython-312.pyc create mode 100644 HybroLang/__pycache__/__init__.cpython-312.pyc create mode 100644 __pycache__/H2Utils.cpython-312.pyc create mode 100644 __pycache__/SwConfig.cpython-312.pyc diff --git a/CodeExamples/Add-With-Specialization.aarch64 b/CodeExamples/Add-With-Specialization.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..0bb07df5ff33162aec601d321e1849c08e3e6031 GIT binary patch literal 39832 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +#include // -*- c -*- +#include + +typedef int (*pifi)(int); + +pifi genAdd(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genADD_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +int main(int argc, char * argv[]) +{ + int in0, in1, res; + pifi fPtr; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 & in2 + in1 = atoi (argv[2]); + fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions + printf("// Compilette for simple addition between 1 variable with\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genAdd (fPtr, in0); // Generate instructions + res = fPtr(in1); // Call generated code + printf("%d + %d = %d\n", in0, in1, res); + if (res == (in0 + in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Add-With-Specialization.power b/CodeExamples/Add-With-Specialization.power new file mode 100755 index 0000000000000000000000000000000000000000..2b39fab45ffaed3d199fd4464e571ef21faf7c55 GIT binary patch literal 78168 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 KPR&I* +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +#include // -*- c -*- +#include + +typedef int (*pifi)(int); + +pifi genAdd(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x780F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genADD_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +int main(int argc, char * argv[]) +{ + int in0, in1, res; + pifi fPtr; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 & in2 + in1 = atoi (argv[2]); + fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions + printf("// Compilette for simple addition between 1 variable with\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genAdd (fPtr, in0); // Generate instructions + res = fPtr(in1); // Call generated code + printf("%d + %d = %d\n", in0, in1, res); + if (res == (in0 + in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Add-With-Specialization.riscv b/CodeExamples/Add-With-Specialization.riscv new file mode 100755 index 0000000000000000000000000000000000000000..bf3a43a6afa1065502cd2044874f927bb40fd210 GIT binary patch literal 29136 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 P<%|3kW23dq5WfEg_7Ue( literal 0 HcmV?d00001 diff --git a/CodeExamples/Add-With-Specialization.riscv.c b/CodeExamples/Add-With-Specialization.riscv.c new file mode 100644 index 0000000..c280d38 --- /dev/null +++ b/CodeExamples/Add-With-Specialization.riscv.c @@ -0,0 +1,667 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +#include // -*- c -*- +#include + +typedef int (*pifi)(int); + +pifi genAdd(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x73F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genADD_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +int main(int argc, char * argv[]) +{ + int in0, in1, res; + pifi fPtr; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 & in2 + in1 = atoi (argv[2]); + fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions + printf("// Compilette for simple addition between 1 variable with\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genAdd (fPtr, in0); // Generate instructions + res = fPtr(in1); // Call generated code + printf("%d + %d = %d\n", in0, in1, res); + if (res == (in0 + in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Add-With-Transprecision.aarch64 b/CodeExamples/Add-With-Transprecision.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..ba791eed19985442f5601c0deb43e65c871b34f5 GIT binary patch literal 43928 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 Put(6-yAAr4l4Sn_3uW)) literal 0 HcmV?d00001 diff --git a/CodeExamples/Add-With-Transprecision.aarch64.c b/CodeExamples/Add-With-Transprecision.aarch64.c new file mode 100644 index 0000000..dad6e14 --- /dev/null +++ b/CodeExamples/Add-With-Transprecision.aarch64.c @@ -0,0 +1,1101 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x72 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x272 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRI_F_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RR_F_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x78810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RI_F_32_1(r0,i0) do /* mv */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_F_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x3d & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RR_F_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x79810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RI_F_64_1(r0,i0) do /* mv */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_FADD_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_FMOV_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_FMOV_RI_F_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_F_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_FMOV_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_FMOV_RI_F_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef float (*pifff)(float, float); +typedef double (*pifdd)(double, double); + +// Simple addition between variables with +// specialization transprecision on data width +// Width depend on the platform. At least 32 & 64 bits. +// Could also be 16 on RISCV or 128 on INTEL + +h2_insn_t * genAdd(h2_insn_t * ptr, int FloatWidth) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + +int main(int argc, char * argv[]) +{ + float in0, in1, resf; + double resd; +#if 0 + long double resD; +#endif + pifff fPtr1; + pifdd fPtr2; + + if (argc < 2) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atof(argv[1]); // Get the users values in1 & in2 + in1 = atof(argv[2]); + fPtr1 = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr2 = h2_malloc (1024); // Allocate memory for 1024 instructions +#if 0 + fPtr1 = genAdd (ptr, 16); // Generate instructions + resf = fPtr1(in0, in1); // Call generated code + printf("(%d) %10.30f + %10.30f = %10.30f\n", 16, in0, in1, resf); +#endif + + fPtr1 = (pifff)genAdd (fPtr1, 32); // Generate instructions + resf = fPtr1(in0, in1); // Call generated code + printf("(%d) %10.30f + %10.30f = %10.30f\n", 32, in0, in1, resf); + + fPtr2 = (pifdd)genAdd (fPtr2, 64); // Generate instructions + resd = fPtr2(in0, in1); // Call generated code + printf("(%d) %10.30lf + %10.30lf = %10.30lf\n", 64, in0, in1, resd); + +#if 0 + fPtr2 = genAdd (ptr, 128); // Generate instructions + resD = fPtr2(in0, in1); // Call generated code + printf("(%d) %10.30Lf + %10.30Lf = %10.30Lf\n", 128, in0, in1, resD); +#endif + + return 0; + +} diff --git a/CodeExamples/Add-With-Transprecision.power b/CodeExamples/Add-With-Transprecision.power new file mode 100755 index 0000000000000000000000000000000000000000..75732780162f3482e581ed1471c2617f4e16dfba GIT binary patch literal 78288 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 I^zick4@5Nx>i_@% literal 0 HcmV?d00001 diff --git a/CodeExamples/Add-With-Transprecision.power.c b/CodeExamples/Add-With-Transprecision.power.c new file mode 100644 index 0000000..591a0e0 --- /dev/null +++ b/CodeExamples/Add-With-Transprecision.power.c @@ -0,0 +1,850 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_FMR_RR_F_32_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); +#define P1_FMR_RR_F_64_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define PPC_FADDS_RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); +#define PPC_FADDS__RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDFP_RRR_F_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xa & 0x7ff) >> 0)); } while(0); +#define P1_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); +#define P1_FADD__RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FADDS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FADDS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDFP_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FADD__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_FMR_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_FMR_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef float (*pifff)(float, float); +typedef double (*pifdd)(double, double); + +// Simple addition between variables with +// specialization transprecision on data width +// Width depend on the platform. At least 32 & 64 bits. +// Could also be 16 on RISCV or 128 on INTEL + +h2_insn_t * genAdd(h2_insn_t * ptr, int FloatWidth) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, (FloatWidth), 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + +int main(int argc, char * argv[]) +{ + float in0, in1, resf; + double resd; +#if 0 + long double resD; +#endif + pifff fPtr1; + pifdd fPtr2; + + if (argc < 2) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atof(argv[1]); // Get the users values in1 & in2 + in1 = atof(argv[2]); + fPtr1 = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr2 = h2_malloc (1024); // Allocate memory for 1024 instructions +#if 0 + fPtr1 = genAdd (ptr, 16); // Generate instructions + resf = fPtr1(in0, in1); // Call generated code + printf("(%d) %10.30f + %10.30f = %10.30f\n", 16, in0, in1, resf); +#endif + + fPtr1 = (pifff)genAdd (fPtr1, 32); // Generate instructions + resf = fPtr1(in0, in1); // Call generated code + printf("(%d) %10.30f + %10.30f = %10.30f\n", 32, in0, in1, resf); + + fPtr2 = (pifdd)genAdd (fPtr2, 64); // Generate instructions + resd = fPtr2(in0, in1); // Call generated code + printf("(%d) %10.30lf + %10.30lf = %10.30lf\n", 64, in0, in1, resd); + +#if 0 + fPtr2 = genAdd (ptr, 128); // Generate instructions + resD = fPtr2(in0, in1); // Call generated code + printf("(%d) %10.30Lf + %10.30Lf = %10.30Lf\n", 128, in0, in1, resD); +#endif + + return 0; + +} diff --git a/CodeExamples/Add-With-Transprecision.riscv b/CodeExamples/Add-With-Transprecision.riscv new file mode 100755 index 0000000000000000000000000000000000000000..538deae5730628be5c5148b3df8a70f1b1e899eb GIT binary patch literal 29136 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32F_FMV_S_RR_F_32_1(r3,r1) do /* MV */ { riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32D_FMV_D_RR_F_64_1(r3,r1) do /* MV */ { riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32F_FADD_S_RRR_F_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32D_FADD_D_RRR_F_64_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FADD_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32D_FADD_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef float (*pifff)(float, float); +typedef double (*pifdd)(double, double); + +// Simple addition between variables with +// specialization transprecision on data width +// Width depend on the platform. At least 32 & 64 bits. +// Could also be 16 on RISCV or 128 on INTEL + +h2_insn_t * genAdd(h2_insn_t * ptr, int FloatWidth) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, (FloatWidth), 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x31F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + +int main(int argc, char * argv[]) +{ + float in0, in1, resf; + double resd; +#if 0 + long double resD; +#endif + pifff fPtr1; + pifdd fPtr2; + + if (argc < 2) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atof(argv[1]); // Get the users values in1 & in2 + in1 = atof(argv[2]); + fPtr1 = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr2 = h2_malloc (1024); // Allocate memory for 1024 instructions +#if 0 + fPtr1 = genAdd (ptr, 16); // Generate instructions + resf = fPtr1(in0, in1); // Call generated code + printf("(%d) %10.30f + %10.30f = %10.30f\n", 16, in0, in1, resf); +#endif + + fPtr1 = (pifff)genAdd (fPtr1, 32); // Generate instructions + resf = fPtr1(in0, in1); // Call generated code + printf("(%d) %10.30f + %10.30f = %10.30f\n", 32, in0, in1, resf); + + fPtr2 = (pifdd)genAdd (fPtr2, 64); // Generate instructions + resd = fPtr2(in0, in1); // Call generated code + printf("(%d) %10.30lf + %10.30lf = %10.30lf\n", 64, in0, in1, resd); + +#if 0 + fPtr2 = genAdd (ptr, 128); // Generate instructions + resD = fPtr2(in0, in1); // Call generated code + printf("(%d) %10.30Lf + %10.30Lf = %10.30Lf\n", 128, in0, in1, resD); +#endif + + return 0; + +} diff --git a/CodeExamples/Array-Ld-flt.aarch64 b/CodeExamples/Array-Ld-flt.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..5fe4e94f5bb0ff172c5cb8f0347f11781a5523ff GIT binary patch literal 48048 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

uG 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 u;P&BG_M_TmDxM@21HxGM +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RR_F_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x78810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RI_F_32_1(r0,i0) do /* mv */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_F_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x3d & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RR_F_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x79810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RI_F_64_1(r0,i0) do /* mv */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_F_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x5e2 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_F_32_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x5e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_F_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_F_64_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x3f5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_F_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_FMOV_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_FMOV_RI_F_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_F_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_FMOV_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_FMOV_RI_F_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef float (*pifii)(float *, int); +typedef double (*pifsi)(double *, int); + +/* C compilette prototype */ +h2_insn_t * genLoad(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 2 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t tmp = {H2REGISTER, 'f', 1, (wordSize), 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0103, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = aarch64_genR_3(tmp0002, tmp0001, immValueZero); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0002, immValueZero); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%4f ", ARRAY[i]); \ + } \ + printf ("\n"); + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resultOK; + float res32; + double res64; + pifii fPtr32; + pifsi fPtr64; + + + float f32[] = {0, 1, 2.2, 3.33, 4.444, 5.5555, 6.66666, 7.777777}; + double f64[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + resultOK = 0; + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) genLoad (ptr, 32); // Generate instructions + res32 = fPtr32(f32, in0); // Call generated code + if (f32[in0] != res32) + resultOK ++; + PRINTARRAY ("32 bits : ", f32, sizeof(f32) / sizeof (float)); + printf ("res (32) f32[%d] = %f\n", in0, res32); + + /* ptr = h2_malloc (1024); // Allocate memory for 1024 instructions */ + /* fPtr64 = (pifsi) genLoad (ptr, 64); // Generate instructions */ + /* res64 = fPtr64(f64, in0); // Call generated code */ + /* if (f64[in0] != res64) */ + /* resultOK ++; */ + /* PRINTARRAY ("64 bits : ", f64, sizeof(f64) / sizeof (double)); */ + /* printf ("res (64) f64[%d] = %f\n", in0, res64); */ + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-Ld-flt.power b/CodeExamples/Array-Ld-flt.power new file mode 100755 index 0000000000000000000000000000000000000000..5a08772e1a8a83f11023bab6f73fb9c9cc7bf1ee GIT binary patch literal 78424 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 B6PN%1 literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-Ld-flt.power.c b/CodeExamples/Array-Ld-flt.power.c new file mode 100644 index 0000000..4c1794b --- /dev/null +++ b/CodeExamples/Array-Ld-flt.power.c @@ -0,0 +1,895 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_FMR_RR_F_32_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); +#define P1_FMR_RR_F_64_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_LFS_RRI_F_32_1(r0,r1,i0) do /* r */ { power_G32(((0x30 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LFS_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_FMR_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_FMR_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef float (*pifii)(float *, int); +typedef double (*pifsi)(double *, int); + +/* C compilette prototype */ +h2_insn_t * genLoad(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 2 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t tmp = {H2REGISTER, 'f', 1, (wordSize), 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x381F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = power_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = power_genR_3(tmp0002, tmp0001, immValueZero); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%4f ", ARRAY[i]); \ + } \ + printf ("\n"); + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resultOK; + float res32; + double res64; + pifii fPtr32; + pifsi fPtr64; + + + float f32[] = {0, 1, 2.2, 3.33, 4.444, 5.5555, 6.66666, 7.777777}; + double f64[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + resultOK = 0; + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) genLoad (ptr, 32); // Generate instructions + res32 = fPtr32(f32, in0); // Call generated code + if (f32[in0] != res32) + resultOK ++; + PRINTARRAY ("32 bits : ", f32, sizeof(f32) / sizeof (float)); + printf ("res (32) f32[%d] = %f\n", in0, res32); + + /* ptr = h2_malloc (1024); // Allocate memory for 1024 instructions */ + /* fPtr64 = (pifsi) genLoad (ptr, 64); // Generate instructions */ + /* res64 = fPtr64(f64, in0); // Call generated code */ + /* if (f64[in0] != res64) */ + /* resultOK ++; */ + /* PRINTARRAY ("64 bits : ", f64, sizeof(f64) / sizeof (double)); */ + /* printf ("res (64) f64[%d] = %f\n", in0, res64); */ + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-Ld-flt.riscv b/CodeExamples/Array-Ld-flt.riscv new file mode 100755 index 0000000000000000000000000000000000000000..5b8138b4212996bfb589bcd8d76b8f9fb034ace8 GIT binary patch literal 33296 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�g$aVmgGaXuh1T>K}Zi2H!r<4@tQp^P6Fv;bK_ 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-Ld-flt.riscv.c b/CodeExamples/Array-Ld-flt.riscv.c new file mode 100644 index 0000000..db41554 --- /dev/null +++ b/CodeExamples/Array-Ld-flt.riscv.c @@ -0,0 +1,815 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32F_FLW_RRI_F_32_1(r2,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r2 & 0x1f) << 7)|((0x7 & 0x7f) >> 0)); } while(0); +#define RV64D_FLW_RRI_F_64_1(r2,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x3 & 0x7) << 12)|((r2 & 0x1f) << 7)|((0x7 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32F_FMV_S_RR_F_32_1(r3,r1) do /* MV */ { riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32D_FMV_D_RR_F_64_1(r3,r1) do /* MV */ { riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32F_FLW_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV64D_FLW_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef float (*pifii)(float *, int); +typedef double (*pifsi)(double *, int); + +/* C compilette prototype */ +h2_insn_t * genLoad(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 2 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t tmp = {H2REGISTER, 'f', 1, (wordSize), 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF1F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); + tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = riscv_genR_3(tmp0002, tmp0001, immValueZero); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%4f ", ARRAY[i]); \ + } \ + printf ("\n"); + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resultOK; + float res32; + double res64; + pifii fPtr32; + pifsi fPtr64; + + + float f32[] = {0, 1, 2.2, 3.33, 4.444, 5.5555, 6.66666, 7.777777}; + double f64[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + resultOK = 0; + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) genLoad (ptr, 32); // Generate instructions + res32 = fPtr32(f32, in0); // Call generated code + if (f32[in0] != res32) + resultOK ++; + PRINTARRAY ("32 bits : ", f32, sizeof(f32) / sizeof (float)); + printf ("res (32) f32[%d] = %f\n", in0, res32); + + /* ptr = h2_malloc (1024); // Allocate memory for 1024 instructions */ + /* fPtr64 = (pifsi) genLoad (ptr, 64); // Generate instructions */ + /* res64 = fPtr64(f64, in0); // Call generated code */ + /* if (f64[in0] != res64) */ + /* resultOK ++; */ + /* PRINTARRAY ("64 bits : ", f64, sizeof(f64) / sizeof (double)); */ + /* printf ("res (64) f64[%d] = %f\n", in0, res64); */ + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-Ld.aarch64 b/CodeExamples/Array-Ld.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..a2a38992e0f9dbf96b355f1b03984d06fd75b0c9 GIT binary patch literal 43952 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 B-tGVZ literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-Ld.aarch64.c b/CodeExamples/Array-Ld.aarch64.c new file mode 100644 index 0000000..af9e00a --- /dev/null +++ b/CodeExamples/Array-Ld.aarch64.c @@ -0,0 +1,1178 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef int (*pifii)(int *, int); +typedef short (*pifsi)(short *, int); +typedef char (*pifci)(char *, int); + +/* C compilette prototype */ +h2_insn_t * genAdd(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 2 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, (wordSize), 0, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, (wordSize), 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = aarch64_genR_3(tmp0002, tmp0001, immValueZero); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0002, immValueZero); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%4d ", ARRAY[i]); \ + } \ + printf ("\n"); + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK; + pifii fPtr32; + pifsi fPtr16; + pifci fPtr8; + + int a32[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; + short a16[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; + char a8[] = {0, 1, 10, 100, 127, 127, 100, 10, 1, 0}; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + resultOK = 0; + printf ("Size of 10 INTs %ld, SHORTs %ld, CHARs %ld \n", sizeof (a32), sizeof (a16), sizeof (a8)); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) genAdd (ptr, 32); // Generate instructions + res = fPtr32(a32, in0); // Call generated code + if (a32[in0] != res) + resultOK ++; + PRINTARRAY ("32 bits : ", a32, sizeof(a32) / sizeof (int)); + printf ("res (32) a32[%d] = %d\n", in0, res); + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr16 = (pifsi) genAdd (ptr, 16); // Generate instructions + res = fPtr16(a16, in0); // Call generated code + PRINTARRAY ("16 bits : ", a16, sizeof(a16) / sizeof (short)); + if (a16[in0] != res) + resultOK ++; + printf ("res (16) a16[%d] = %d\n", in0, res); + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr8 = (pifci) genAdd (ptr, 8); // Generate instructions + res = fPtr8(a8, in0); // Call generated code + if (a8[in0] != res) + resultOK ++; + PRINTARRAY ("8 bits : ", a8, sizeof(a8) / sizeof (char)); + printf ("res (8) a8[%d] = %d\n", in0, res); + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-Ld.power b/CodeExamples/Array-Ld.power new file mode 100755 index 0000000000000000000000000000000000000000..406a0507411ffcf3551cb197a8c1b4ebde81eb83 GIT binary patch literal 78192 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 MPp_hykEAI3|N55}kN^Mx literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-Ld.power.c b/CodeExamples/Array-Ld.power.c new file mode 100644 index 0000000..11e0390 --- /dev/null +++ b/CodeExamples/Array-Ld.power.c @@ -0,0 +1,882 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef int (*pifii)(int *, int); +typedef short (*pifsi)(short *, int); +typedef char (*pifci)(char *, int); + +/* C compilette prototype */ +h2_insn_t * genAdd(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 2 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, (wordSize), 3, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, (wordSize), 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x781F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = power_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = power_genR_3(tmp0002, tmp0001, immValueZero); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%4d ", ARRAY[i]); \ + } \ + printf ("\n"); + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK; + pifii fPtr32; + pifsi fPtr16; + pifci fPtr8; + + int a32[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; + short a16[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; + char a8[] = {0, 1, 10, 100, 127, 127, 100, 10, 1, 0}; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + resultOK = 0; + printf ("Size of 10 INTs %ld, SHORTs %ld, CHARs %ld \n", sizeof (a32), sizeof (a16), sizeof (a8)); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) genAdd (ptr, 32); // Generate instructions + res = fPtr32(a32, in0); // Call generated code + if (a32[in0] != res) + resultOK ++; + PRINTARRAY ("32 bits : ", a32, sizeof(a32) / sizeof (int)); + printf ("res (32) a32[%d] = %d\n", in0, res); + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr16 = (pifsi) genAdd (ptr, 16); // Generate instructions + res = fPtr16(a16, in0); // Call generated code + PRINTARRAY ("16 bits : ", a16, sizeof(a16) / sizeof (short)); + if (a16[in0] != res) + resultOK ++; + printf ("res (16) a16[%d] = %d\n", in0, res); + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr8 = (pifci) genAdd (ptr, 8); // Generate instructions + res = fPtr8(a8, in0); // Call generated code + if (a8[in0] != res) + resultOK ++; + PRINTARRAY ("8 bits : ", a8, sizeof(a8) / sizeof (char)); + printf ("res (8) a8[%d] = %d\n", in0, res); + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-Ld.riscv b/CodeExamples/Array-Ld.riscv new file mode 100755 index 0000000000000000000000000000000000000000..6785e5c7406b813e93dffc28b3461b6e4e53cd62 GIT binary patch literal 33248 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 lK?t<70{yv<`Ok9Pbgfg7t5r=qAl`U);?~I+t +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef int (*pifii)(int *, int); +typedef short (*pifsi)(short *, int); +typedef char (*pifci)(char *, int); + +/* C compilette prototype */ +h2_insn_t * genAdd(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 2 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, (wordSize), 10, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, (wordSize), 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF3F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); + tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = riscv_genR_3(tmp0002, tmp0001, immValueZero); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%4d ", ARRAY[i]); \ + } \ + printf ("\n"); + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK; + pifii fPtr32; + pifsi fPtr16; + pifci fPtr8; + + int a32[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; + short a16[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; + char a8[] = {0, 1, 10, 100, 127, 127, 100, 10, 1, 0}; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + resultOK = 0; + printf ("Size of 10 INTs %ld, SHORTs %ld, CHARs %ld \n", sizeof (a32), sizeof (a16), sizeof (a8)); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) genAdd (ptr, 32); // Generate instructions + res = fPtr32(a32, in0); // Call generated code + if (a32[in0] != res) + resultOK ++; + PRINTARRAY ("32 bits : ", a32, sizeof(a32) / sizeof (int)); + printf ("res (32) a32[%d] = %d\n", in0, res); + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr16 = (pifsi) genAdd (ptr, 16); // Generate instructions + res = fPtr16(a16, in0); // Call generated code + PRINTARRAY ("16 bits : ", a16, sizeof(a16) / sizeof (short)); + if (a16[in0] != res) + resultOK ++; + printf ("res (16) a16[%d] = %d\n", in0, res); + + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr8 = (pifci) genAdd (ptr, 8); // Generate instructions + res = fPtr8(a8, in0); // Call generated code + if (a8[in0] != res) + resultOK ++; + PRINTARRAY ("8 bits : ", a8, sizeof(a8) / sizeof (char)); + printf ("res (8) a8[%d] = %d\n", in0, res); + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-Mult-Specialization.aarch64 b/CodeExamples/Array-Mult-Specialization.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..5f29e67b077e9bbe10576173bf02cfc097a84fde GIT binary patch literal 48416 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_GE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include +#include + +typedef int (*pifi)(int *); +pifi genMulArray(pifi ptr, int b, int len) +{ + /* Code Generation of 12 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t l = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0701, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + l = aarch64_genMV_3(l, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((len))}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, l); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0002 = aarch64_genMUL_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0003 = aarch64_genADD_3(tmp0003, a, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = aarch64_genMUL_3(tmp0004, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0005 = aarch64_genADD_3(tmp0005, a, tmp0004); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = aarch64_genR_3(tmp0006, tmp0005, immValueZero); + tmp0007 = aarch64_genMUL_3(tmp0007, tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); + aarch64_genW_3(tmp0003, tmp0007, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +void printArray(int * array, int len) +{ + printf ("Array values (%d) : ", len); + for (int i = 0; i < len; i++) + printf ("%d ", array[i]); + printf ("\n"); +} + +void mulArray(int * array, int len, int value) +{ + for (int i = 0; i < len; i++) + array[i] = array[i] * value; +} + +int main(int argc, char * argv[]) +{ + int arrayLen, mulValue, i, resultOK; + pifi fPtr; + int *array1, *array2; + clock_t startC, stopC, startHg, stopHg; + + if (argc < 3) + { + printf("Give 2 values (array len & mult. coefficient )\n"); + exit(-1); + } + arrayLen = atoi (argv[1]); // Get the + mulValue = atoi (argv[2]); + array1 = calloc (arrayLen, sizeof (int)); + array2 = calloc (arrayLen, sizeof (int)); + for (i = 0; i < arrayLen; i++) + { + array1[i] = random () % 100; + array2[i] = array1[i]; + } + printArray (array1, arrayLen); + printf("// Multiply an array with a constant value\n"); + printf("// Array len = %d constant value %d\n", arrayLen, mulValue); + // Allocate memory for 1024 instructions, generate kernel + fPtr = genMulArray ((pifi) h2_malloc (1024), mulValue, arrayLen); + startHg = clock(); + fPtr(array1); // Call generated code + stopHg = clock(); + printArray (array1, arrayLen); + resultOK = 0; + startC = clock(); + mulArray (array2, arrayLen, mulValue); + stopC = clock(); + printf ("C version %ld Hg version %ld\n\n", stopC - startC, stopHg - startHg); + for (int i = 0; i < arrayLen; i++) + { + if (array2[i] != array1[i]) + { + printf("Erreur multiplication!\n"); + resultOK = -1; + break; + } + } + return resultOK; +} diff --git a/CodeExamples/Array-Mult-Specialization.power b/CodeExamples/Array-Mult-Specialization.power new file mode 100755 index 0000000000000000000000000000000000000000..077f0dbdab2d6e9d6c958470df624c5e5e285a5b GIT binary patch literal 78720 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 NKD~-;KGL%6zX99T4r~Ab literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-Mult-Specialization.power.c b/CodeExamples/Array-Mult-Specialization.power.c new file mode 100644 index 0000000..10fa011 --- /dev/null +++ b/CodeExamples/Array-Mult-Specialization.power.c @@ -0,0 +1,1052 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genBGE_1(h2_sValue_t P0); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BGE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include +#include + +typedef int (*pifi)(int *); +pifi genMulArray(pifi ptr, int b, int len) +{ + /* Code Generation of 12 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t l = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF80F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + l = power_genMV_2(l, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((len))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, l); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0002 = power_genMUL_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0003 = power_genADD_3(tmp0003, a, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = power_genMUL_3(tmp0004, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0005 = power_genADD_3(tmp0005, a, tmp0004); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = power_genR_3(tmp0006, tmp0005, immValueZero); + tmp0007 = power_genMUL_3(tmp0007, tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); + power_genW_3(tmp0003, tmp0007, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +void printArray(int * array, int len) +{ + printf ("Array values (%d) : ", len); + for (int i = 0; i < len; i++) + printf ("%d ", array[i]); + printf ("\n"); +} + +void mulArray(int * array, int len, int value) +{ + for (int i = 0; i < len; i++) + array[i] = array[i] * value; +} + +int main(int argc, char * argv[]) +{ + int arrayLen, mulValue, i, resultOK; + pifi fPtr; + int *array1, *array2; + clock_t startC, stopC, startHg, stopHg; + + if (argc < 3) + { + printf("Give 2 values (array len & mult. coefficient )\n"); + exit(-1); + } + arrayLen = atoi (argv[1]); // Get the + mulValue = atoi (argv[2]); + array1 = calloc (arrayLen, sizeof (int)); + array2 = calloc (arrayLen, sizeof (int)); + for (i = 0; i < arrayLen; i++) + { + array1[i] = random () % 100; + array2[i] = array1[i]; + } + printArray (array1, arrayLen); + printf("// Multiply an array with a constant value\n"); + printf("// Array len = %d constant value %d\n", arrayLen, mulValue); + // Allocate memory for 1024 instructions, generate kernel + fPtr = genMulArray ((pifi) h2_malloc (1024), mulValue, arrayLen); + startHg = clock(); + fPtr(array1); // Call generated code + stopHg = clock(); + printArray (array1, arrayLen); + resultOK = 0; + startC = clock(); + mulArray (array2, arrayLen, mulValue); + stopC = clock(); + printf ("C version %ld Hg version %ld\n\n", stopC - startC, stopHg - startHg); + for (int i = 0; i < arrayLen; i++) + { + if (array2[i] != array1[i]) + { + printf("Erreur multiplication!\n"); + resultOK = -1; + break; + } + } + return resultOK; +} diff --git a/CodeExamples/Array-Mult-Specialization.riscv b/CodeExamples/Array-Mult-Specialization.riscv new file mode 100755 index 0000000000000000000000000000000000000000..4aa1d4f2ecd1180a921acc40650398f5b9311358 GIT binary patch literal 37596 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 UYSMJt +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include +#include + +typedef int (*pifi)(int *); +pifi genMulArray(pifi ptr, int b, int len) +{ + /* Code Generation of 11 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t l = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x77F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + l = riscv_genMV_2(l, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((len))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGE_3(i, l, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0002 = riscv_genMUL_4(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0003 = riscv_genADD_3(tmp0003, a, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = riscv_genMUL_4(tmp0004, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0005 = riscv_genADD_3(tmp0005, a, tmp0004); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = riscv_genR_3(tmp0006, tmp0005, immValueZero); + tmp0007 = riscv_genMUL_4(tmp0007, tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); + if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); + riscv_genW_3(tmp0003, tmp0007, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000001]; + i = riscv_genBGE_3(i, l, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +void printArray(int * array, int len) +{ + printf ("Array values (%d) : ", len); + for (int i = 0; i < len; i++) + printf ("%d ", array[i]); + printf ("\n"); +} + +void mulArray(int * array, int len, int value) +{ + for (int i = 0; i < len; i++) + array[i] = array[i] * value; +} + +int main(int argc, char * argv[]) +{ + int arrayLen, mulValue, i, resultOK; + pifi fPtr; + int *array1, *array2; + clock_t startC, stopC, startHg, stopHg; + + if (argc < 3) + { + printf("Give 2 values (array len & mult. coefficient )\n"); + exit(-1); + } + arrayLen = atoi (argv[1]); // Get the + mulValue = atoi (argv[2]); + array1 = calloc (arrayLen, sizeof (int)); + array2 = calloc (arrayLen, sizeof (int)); + for (i = 0; i < arrayLen; i++) + { + array1[i] = random () % 100; + array2[i] = array1[i]; + } + printArray (array1, arrayLen); + printf("// Multiply an array with a constant value\n"); + printf("// Array len = %d constant value %d\n", arrayLen, mulValue); + // Allocate memory for 1024 instructions, generate kernel + fPtr = genMulArray ((pifi) h2_malloc (1024), mulValue, arrayLen); + startHg = clock(); + fPtr(array1); // Call generated code + stopHg = clock(); + printArray (array1, arrayLen); + resultOK = 0; + startC = clock(); + mulArray (array2, arrayLen, mulValue); + stopC = clock(); + printf ("C version %ld Hg version %ld\n\n", stopC - startC, stopHg - startHg); + for (int i = 0; i < arrayLen; i++) + { + if (array2[i] != array1[i]) + { + printf("Erreur multiplication!\n"); + resultOK = -1; + break; + } + } + return resultOK; +} diff --git a/CodeExamples/Array-St-flt.aarch64 b/CodeExamples/Array-St-flt.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..d2163ddebe7e345e7e3693996edcc83b6672f8a7 GIT binary patch literal 48112 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_F_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_F_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STUR_RRI_F_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_F_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STUR_RRI_F_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_F_128_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1e4 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_F_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_F_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_F_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STUR_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STUR_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 128) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_F_128_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef float (*pifii)(float *, int, float); +typedef double (*pifsi)(double *, int, double); + +/* C compilette prototype */ +h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t value = {H2REGISTER, 'f', 1, (wordSize), 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0103, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + aarch64_genW_3(tmp0001, value, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ + for (int i = 0; i < LIMIT; i++) \ + { \ + if (INDICE == i) \ + { \ + if (ARRAY[INDICE] != VALUE) \ + { \ + RESULT ++; \ + } \ + } \ + else \ + { \ + if (ARRAY[i] != (float) i) \ + { \ + RESULT ++; \ + } \ + } \ + } + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%2.2f ", ARRAY[i]); \ + } \ + printf ("\n"); + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resultOK, loopLimit; + float in132, res32; + double in164, res64; + pifii fPtr32; + pifsi fPtr64; + + float f32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + double f64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + + in0 = atoi (argv[1]); // Get index value + in164 = in132 = atof (argv[2]); // fp number to store + resultOK = 0; + loopLimit = sizeof(f32) / sizeof (float); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) gen_Array_St(ptr, 32); // Generate instructions + res32 = fPtr32(f32, in0, in132); // Call generated code + printf("%2.2f, %2.2f\n", f32[in0], in132); + CHECK (f32, in0, resultOK, loopLimit, in132); + PRINTARRAY("32 bits : ", f32, loopLimit); + printf ("ResultOK %d\n", resultOK); + + loopLimit = sizeof(f64) / sizeof (double); + fPtr64 = (pifii) gen_Array_St(ptr, 64); // Generate instructions + res64 = fPtr64(f64, in0, in164); // Call generated code + printf("%2.2f, %2.2f\n", f64[in0], in164); + CHECK (f64, in0, resultOK, loopLimit, in164); + PRINTARRAY("64 bits : ", f64, loopLimit); + printf ("ResultOK %d\n", resultOK); + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-St-flt.power b/CodeExamples/Array-St-flt.power new file mode 100755 index 0000000000000000000000000000000000000000..652c5e42a177b7c559ea7c32694a4c39e52b9183 GIT binary patch literal 78544 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%0DA1zcgQJXY3`J zKS>Ptr$SO!8Kgk6J*U#-@8fSQ(d)t^H7BWKLuvA#qK#M_PpW~%V~OUIG4uE^o@7~iyPJ5)_~lL$l7-6g@!Z2@DLu3=tin=+lclo+cXd)?Qj`^fk<23n z@k<0Z&b19+lJTckU*DC#p&6D!Xtv0oET3E!#gicBYFsjZd9Khp4}_istNy3_KmFb( j31XhXGf$MXQVm?r9c?SEFH+_I907yl#-s`-McMxaKA8Jw literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-St-flt.power.c b/CodeExamples/Array-St-flt.power.c new file mode 100644 index 0000000..2b64842 --- /dev/null +++ b/CodeExamples/Array-St-flt.power.c @@ -0,0 +1,909 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_STFS_RRI_F_32_1(r1,r0,i0) do /* w */ { power_G32(((0x34 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STFD_RRI_F_64_1(r1,r0,i0) do /* w */ { power_G32(((0x36 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STFS_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STFD_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef float (*pifii)(float *, int, float); +typedef double (*pifsi)(double *, int, double); + +/* C compilette prototype */ +h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t value = {H2REGISTER, 'f', 1, (wordSize), 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x381F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = power_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + power_genW_3(tmp0001, value, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ + for (int i = 0; i < LIMIT; i++) \ + { \ + if (INDICE == i) \ + { \ + if (ARRAY[INDICE] != VALUE) \ + { \ + RESULT ++; \ + } \ + } \ + else \ + { \ + if (ARRAY[i] != (float) i) \ + { \ + RESULT ++; \ + } \ + } \ + } + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%2.2f ", ARRAY[i]); \ + } \ + printf ("\n"); + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resultOK, loopLimit; + float in132, res32; + double in164, res64; + pifii fPtr32; + pifsi fPtr64; + + float f32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + double f64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + + in0 = atoi (argv[1]); // Get index value + in164 = in132 = atof (argv[2]); // fp number to store + resultOK = 0; + loopLimit = sizeof(f32) / sizeof (float); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) gen_Array_St(ptr, 32); // Generate instructions + res32 = fPtr32(f32, in0, in132); // Call generated code + printf("%2.2f, %2.2f\n", f32[in0], in132); + CHECK (f32, in0, resultOK, loopLimit, in132); + PRINTARRAY("32 bits : ", f32, loopLimit); + printf ("ResultOK %d\n", resultOK); + + loopLimit = sizeof(f64) / sizeof (double); + fPtr64 = (pifii) gen_Array_St(ptr, 64); // Generate instructions + res64 = fPtr64(f64, in0, in164); // Call generated code + printf("%2.2f, %2.2f\n", f64[in0], in164); + CHECK (f64, in0, resultOK, loopLimit, in164); + PRINTARRAY("64 bits : ", f64, loopLimit); + printf ("ResultOK %d\n", resultOK); + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-St-flt.riscv b/CodeExamples/Array-St-flt.riscv new file mode 100755 index 0000000000000000000000000000000000000000..29fa139cbb89c72cecd6d6422cdbca563d5e9e38 GIT binary patch literal 33332 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32F_FSW_RRI_F_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x27 & 0x7f) >> 0)); } while(0); +#define RV64D_FSW_RRI_F_64_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x3 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x27 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32F_FSW_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'f') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV64D_FSW_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef float (*pifii)(float *, int, float); +typedef double (*pifsi)(double *, int, double); + +/* C compilette prototype */ +h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t value = {H2REGISTER, 'f', 1, (wordSize), 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF1F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); + tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + riscv_genW_3(tmp0001, value, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ + for (int i = 0; i < LIMIT; i++) \ + { \ + if (INDICE == i) \ + { \ + if (ARRAY[INDICE] != VALUE) \ + { \ + RESULT ++; \ + } \ + } \ + else \ + { \ + if (ARRAY[i] != (float) i) \ + { \ + RESULT ++; \ + } \ + } \ + } + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf("%2.2f ", ARRAY[i]); \ + } \ + printf ("\n"); + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resultOK, loopLimit; + float in132, res32; + double in164, res64; + pifii fPtr32; + pifsi fPtr64; + + float f32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + double f64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + + in0 = atoi (argv[1]); // Get index value + in164 = in132 = atof (argv[2]); // fp number to store + resultOK = 0; + loopLimit = sizeof(f32) / sizeof (float); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) gen_Array_St(ptr, 32); // Generate instructions + res32 = fPtr32(f32, in0, in132); // Call generated code + printf("%2.2f, %2.2f\n", f32[in0], in132); + CHECK (f32, in0, resultOK, loopLimit, in132); + PRINTARRAY("32 bits : ", f32, loopLimit); + printf ("ResultOK %d\n", resultOK); + + loopLimit = sizeof(f64) / sizeof (double); + fPtr64 = (pifii) gen_Array_St(ptr, 64); // Generate instructions + res64 = fPtr64(f64, in0, in164); // Call generated code + printf("%2.2f, %2.2f\n", f64[in0], in164); + CHECK (f64, in0, resultOK, loopLimit, in164); + PRINTARRAY("64 bits : ", f64, loopLimit); + printf ("ResultOK %d\n", resultOK); + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Array-St.aarch64 b/CodeExamples/Array-St.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..46f3931aa6143e3c437560d01afc4c63e1c579c4 GIT binary patch literal 48056 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-St.aarch64.c b/CodeExamples/Array-St.aarch64.c new file mode 100644 index 0000000..728a082 --- /dev/null +++ b/CodeExamples/Array-St.aarch64.c @@ -0,0 +1,1205 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef int (*pifli)(long int *, int, long int); +typedef int (*pifii)(int *, int, int); +typedef int (*pifsi)(short *, int, short); +typedef int (*pifci)(char *, int, char); + +/* C compilette prototype */ +h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t value = {H2REGISTER, 'i', 1, (wordSize), 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0107, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + aarch64_genW_3(tmp0001, value, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ + for (int i = 0; i < LIMIT; i++) \ + { \ + if (INDICE == i) \ + { \ + if (ARRAY[INDICE] != VALUE) \ + { \ + RESULT ++; \ + } \ + } \ + else \ + { \ + if (ARRAY[i] != i) \ + { \ + RESULT ++; \ + } \ + } \ + } + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf(" %2d ", ARRAY[i]); \ + } \ + printf ("\n"); + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK, loopLimit; + pifli fPtr64; + pifii fPtr32; + pifsi fPtr16; + pifci fPtr8; + + + if (argc < 2) + { + printf("Give 1 value\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + printf ("Size of LONG INT %ld, INTs %ld, SHORTs %ld, CHARs %ld\n", sizeof (long int), sizeof (int), sizeof (short), sizeof (char)); + resultOK = 0; + + long int a64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a64) / sizeof (long int); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr64 = (pifii) gen_Array_St(ptr, 8 * sizeof (long int)); // Generate instructions + res = fPtr64(a64, in0, 42); // Call generated code + CHECK (a64, in0, resultOK, loopLimit, 42); + PRINTARRAY("64 bits : ", a64, loopLimit); + + int a32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a32) / sizeof (int); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) gen_Array_St(ptr, 8 * sizeof (int)); // Generate instructions + res = fPtr32(a32, in0, 42); // Call generated code + CHECK (a32, in0, resultOK, loopLimit, 42); + PRINTARRAY("32 bits : ", a32, loopLimit); + + short a16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a16) / sizeof (short); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr16 = (pifsi) gen_Array_St(ptr, 8 * sizeof (short)); // Generate instructions + res = fPtr16(a16, in0, 42); // Call generated code + PRINTARRAY("16 bits : ", a16, loopLimit); + CHECK (a16, in0, resultOK, loopLimit, 42); + + char a8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a8) / sizeof (char); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr8 = (pifci) gen_Array_St(ptr, 8 * sizeof (char)); // Generate instructions + res = fPtr8(a8, in0, 42); // Call generated code + CHECK (a8, in0, resultOK, loopLimit, 42); + PRINTARRAY("8 bits : ", a8, loopLimit); + + if (resultOK != 0) + return -1; + return 0; +} diff --git a/CodeExamples/Array-St.power b/CodeExamples/Array-St.power new file mode 100755 index 0000000000000000000000000000000000000000..6965a9b9ef372956b4fbb5adc0aee89a3dbfcda2 GIT binary patch literal 78304 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�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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-St.power.c b/CodeExamples/Array-St.power.c new file mode 100644 index 0000000..a90192b --- /dev/null +++ b/CodeExamples/Array-St.power.c @@ -0,0 +1,909 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef int (*pifli)(long int *, int, long int); +typedef int (*pifii)(int *, int, int); +typedef int (*pifsi)(short *, int, short); +typedef int (*pifci)(char *, int, char); + +/* C compilette prototype */ +h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t value = {H2REGISTER, 'i', 1, (wordSize), 5, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x383F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); + tmp0001 = power_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + power_genW_3(tmp0001, value, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ + for (int i = 0; i < LIMIT; i++) \ + { \ + if (INDICE == i) \ + { \ + if (ARRAY[INDICE] != VALUE) \ + { \ + RESULT ++; \ + } \ + } \ + else \ + { \ + if (ARRAY[i] != i) \ + { \ + RESULT ++; \ + } \ + } \ + } + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf(" %2d ", ARRAY[i]); \ + } \ + printf ("\n"); + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK, loopLimit; + pifli fPtr64; + pifii fPtr32; + pifsi fPtr16; + pifci fPtr8; + + + if (argc < 2) + { + printf("Give 1 value\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + printf ("Size of LONG INT %ld, INTs %ld, SHORTs %ld, CHARs %ld\n", sizeof (long int), sizeof (int), sizeof (short), sizeof (char)); + resultOK = 0; + + long int a64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a64) / sizeof (long int); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr64 = (pifii) gen_Array_St(ptr, 8 * sizeof (long int)); // Generate instructions + res = fPtr64(a64, in0, 42); // Call generated code + CHECK (a64, in0, resultOK, loopLimit, 42); + PRINTARRAY("64 bits : ", a64, loopLimit); + + int a32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a32) / sizeof (int); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) gen_Array_St(ptr, 8 * sizeof (int)); // Generate instructions + res = fPtr32(a32, in0, 42); // Call generated code + CHECK (a32, in0, resultOK, loopLimit, 42); + PRINTARRAY("32 bits : ", a32, loopLimit); + + short a16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a16) / sizeof (short); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr16 = (pifsi) gen_Array_St(ptr, 8 * sizeof (short)); // Generate instructions + res = fPtr16(a16, in0, 42); // Call generated code + PRINTARRAY("16 bits : ", a16, loopLimit); + CHECK (a16, in0, resultOK, loopLimit, 42); + + char a8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a8) / sizeof (char); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr8 = (pifci) gen_Array_St(ptr, 8 * sizeof (char)); // Generate instructions + res = fPtr8(a8, in0, 42); // Call generated code + CHECK (a8, in0, resultOK, loopLimit, 42); + PRINTARRAY("8 bits : ", a8, loopLimit); + + if (resultOK != 0) + return -1; + return 0; +} diff --git a/CodeExamples/Array-St.riscv b/CodeExamples/Array-St.riscv new file mode 100755 index 0000000000000000000000000000000000000000..a53c8cb343de46718a54e0f720fbbacecf9a567c GIT binary patch literal 33256 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-St.riscv.c b/CodeExamples/Array-St.riscv.c new file mode 100644 index 0000000..6b54d58 --- /dev/null +++ b/CodeExamples/Array-St.riscv.c @@ -0,0 +1,822 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 1 pointer, an index and return int */ +typedef int (*pifli)(long int *, int, long int); +typedef int (*pifii)(int *, int, int); +typedef int (*pifsi)(short *, int, short); +typedef int (*pifci)(char *, int, char); + +/* C compilette prototype */ +h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t value = {H2REGISTER, 'i', 1, (wordSize), 12, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1F1F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); + tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + riscv_genW_3(tmp0001, value, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ + for (int i = 0; i < LIMIT; i++) \ + { \ + if (INDICE == i) \ + { \ + if (ARRAY[INDICE] != VALUE) \ + { \ + RESULT ++; \ + } \ + } \ + else \ + { \ + if (ARRAY[i] != i) \ + { \ + RESULT ++; \ + } \ + } \ + } + +#define PRINTARRAY(MSG, ARRAY, LIMIT)\ + printf (MSG); \ + for (int i = 0; i < LIMIT; i++) \ + { \ + printf(" %2d ", ARRAY[i]); \ + } \ + printf ("\n"); + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK, loopLimit; + pifli fPtr64; + pifii fPtr32; + pifsi fPtr16; + pifci fPtr8; + + + if (argc < 2) + { + printf("Give 1 value\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 + printf ("Size of LONG INT %ld, INTs %ld, SHORTs %ld, CHARs %ld\n", sizeof (long int), sizeof (int), sizeof (short), sizeof (char)); + resultOK = 0; + + long int a64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a64) / sizeof (long int); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr64 = (pifii) gen_Array_St(ptr, 8 * sizeof (long int)); // Generate instructions + res = fPtr64(a64, in0, 42); // Call generated code + CHECK (a64, in0, resultOK, loopLimit, 42); + PRINTARRAY("64 bits : ", a64, loopLimit); + + int a32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a32) / sizeof (int); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr32 = (pifii) gen_Array_St(ptr, 8 * sizeof (int)); // Generate instructions + res = fPtr32(a32, in0, 42); // Call generated code + CHECK (a32, in0, resultOK, loopLimit, 42); + PRINTARRAY("32 bits : ", a32, loopLimit); + + short a16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a16) / sizeof (short); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr16 = (pifsi) gen_Array_St(ptr, 8 * sizeof (short)); // Generate instructions + res = fPtr16(a16, in0, 42); // Call generated code + PRINTARRAY("16 bits : ", a16, loopLimit); + CHECK (a16, in0, resultOK, loopLimit, 42); + + char a8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + loopLimit = sizeof(a8) / sizeof (char); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr8 = (pifci) gen_Array_St(ptr, 8 * sizeof (char)); // Generate instructions + res = fPtr8(a8, in0, 42); // Call generated code + CHECK (a8, in0, resultOK, loopLimit, 42); + PRINTARRAY("8 bits : ", a8, loopLimit); + + if (resultOK != 0) + return -1; + return 0; +} diff --git a/CodeExamples/Array-Sum-2D.aarch64 b/CodeExamples/Array-Sum-2D.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..2696a911a59ff2cf42f7e908bdd9b1c704fe4397 GIT binary patch literal 52312 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�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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_GE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int(*pifpii)(int *, int, int); + +// Sum a 2D array with a constant +// Code specialisation on stride and constant value +pifpii genAddArray2D(pifpii ptr, int stride, int constant) /* C compilette prototype */ +{ + /* Code Generation of 22 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t nLine = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t nColumn = {H2REGISTER, 'i', 1, 32, 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0F07, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + sum = aarch64_genMV_3(sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = aarch64_genMV_3(line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = aarch64_genCMP_2(line, nLine); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = aarch64_genMV_3(column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = aarch64_genCMP_2(column, nColumn); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0003 = aarch64_genMUL_3(tmp0003, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((stride))}); + tmp0004 = aarch64_genADD_3(tmp0004, tmp0003, column); + if (!tmp0004.dontFree) h2_freeReg(tmp0003.regNro); + tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = aarch64_genADD_3(tmp0006, a, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = aarch64_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = aarch64_genADD_3(tmp0008, sum, tmp0007); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = aarch64_genADD_3(sum, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((constant))}); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = aarch64_genADD_3(column, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = aarch64_genADD_3(line, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, sum, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +int sumArray(int nLine, int nColumn, int a[nLine][nColumn], int constant) +{ + int sum = 0; + for (int line = 0; line < nLine; line = line + 1) + for (int column = 0; column < nColumn; column = column + 1) + sum = sum + a[line][column] + constant; + return sum; +} + +int main(int argc, char * argv[]) +{ + pifpii ptr; + int in0, resultH, resultS; + int constant, nLine, nColumn; + + if (argc < 3) + { + printf ("./%s \n", argv[0]); + exit(-1); + } + nLine = atoi(argv[1]); + nColumn = atoi(argv[2]); + constant = atoi(argv[3]); + + printf ("Array %dx%d. Constant Value %d\n", nLine, nColumn, constant); + int a32[nLine][nColumn]; // Create & fill the array + for (int line = 0; line < nLine; line++) + { + printf ("%d: ", line); + for (int column = 0; column < nColumn; column++) + { + a32[line][column] = line+column; + printf ("%d ", a32[line][column]); + } + printf ("\n"); + } + ptr = (pifpii) genAddArray2D (h2_malloc (1024), nColumn, constant);// Generate instructions + resultH = ptr((int *)a32, nLine, nColumn); // Call generated code + + resultS = sumArray(nLine, nColumn, a32, constant); + printf ("%d %d\n", resultH, resultS); + if (resultS == resultH) + return 0; + else + return -1; + +} diff --git a/CodeExamples/Array-Sum-2D.power b/CodeExamples/Array-Sum-2D.power new file mode 100755 index 0000000000000000000000000000000000000000..c8addeb9d750a8f9c08b247293f482866053ef8e GIT binary patch literal 78352 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Array-Sum-2D.power.c b/CodeExamples/Array-Sum-2D.power.c new file mode 100644 index 0000000..70c270e --- /dev/null +++ b/CodeExamples/Array-Sum-2D.power.c @@ -0,0 +1,1110 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBGE_1(h2_sValue_t P0); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BGE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int(*pifpii)(int *, int, int); + +// Sum a 2D array with a constant +// Code specialisation on stride and constant value +pifpii genAddArray2D(pifpii ptr, int stride, int constant) /* C compilette prototype */ +{ + /* Code Generation of 22 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t nLine = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t nColumn = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1F83F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + sum = power_genMV_2(sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = power_genMV_2(line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = power_genCMP_2(line, nLine); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = power_genMV_2(column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = power_genCMP_2(column, nColumn); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0003 = power_genMUL_3(tmp0003, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((stride))}); + tmp0004 = power_genADD_3(tmp0004, tmp0003, column); + if (!tmp0004.dontFree) h2_freeReg(tmp0003.regNro); + tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = power_genADD_3(tmp0006, a, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = power_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = power_genADD_3(tmp0008, sum, tmp0007); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = power_genADD_3(sum, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((constant))}); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = power_genADD_3(column, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = power_genADD_3(line, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, sum); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +int sumArray(int nLine, int nColumn, int a[nLine][nColumn], int constant) +{ + int sum = 0; + for (int line = 0; line < nLine; line = line + 1) + for (int column = 0; column < nColumn; column = column + 1) + sum = sum + a[line][column] + constant; + return sum; +} + +int main(int argc, char * argv[]) +{ + pifpii ptr; + int in0, resultH, resultS; + int constant, nLine, nColumn; + + if (argc < 3) + { + printf ("./%s \n", argv[0]); + exit(-1); + } + nLine = atoi(argv[1]); + nColumn = atoi(argv[2]); + constant = atoi(argv[3]); + + printf ("Array %dx%d. Constant Value %d\n", nLine, nColumn, constant); + int a32[nLine][nColumn]; // Create & fill the array + for (int line = 0; line < nLine; line++) + { + printf ("%d: ", line); + for (int column = 0; column < nColumn; column++) + { + a32[line][column] = line+column; + printf ("%d ", a32[line][column]); + } + printf ("\n"); + } + ptr = (pifpii) genAddArray2D (h2_malloc (1024), nColumn, constant);// Generate instructions + resultH = ptr((int *)a32, nLine, nColumn); // Call generated code + + resultS = sumArray(nLine, nColumn, a32, constant); + printf ("%d %d\n", resultH, resultS); + if (resultS == resultH) + return 0; + else + return -1; + +} diff --git a/CodeExamples/Array-Sum-2D.riscv b/CodeExamples/Array-Sum-2D.riscv new file mode 100755 index 0000000000000000000000000000000000000000..80c5e7ead5d7ee0b2785ff843fead7681112aec0 GIT binary patch literal 41540 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int(*pifpii)(int *, int, int); + +// Sum a 2D array with a constant +// Code specialisation on stride and constant value +pifpii genAddArray2D(pifpii ptr, int stride, int constant) /* C compilette prototype */ +{ + /* Code Generation of 20 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t nLine = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t nColumn = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1FFF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + sum = riscv_genMV_2(sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = riscv_genMV_2(line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = riscv_genBGE_3(line, nLine, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = riscv_genMV_2(column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = riscv_genBGE_3(column, nColumn, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0003 = riscv_genMUL_4(tmp0003, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((stride))}, immValueZero); + tmp0004 = riscv_genADD_3(tmp0004, tmp0003, column); + if (!tmp0004.dontFree) h2_freeReg(tmp0003.regNro); + tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = riscv_genADD_3(tmp0006, a, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = riscv_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = riscv_genADD_3(tmp0008, sum, tmp0007); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = riscv_genADD_3(sum, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((constant))}); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + column = riscv_genADD_3(column, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + line = riscv_genADD_3(line, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, sum); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000005]; + line = riscv_genBGE_3(line, nLine, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000001]; + column = riscv_genBGE_3(column, nColumn, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +int sumArray(int nLine, int nColumn, int a[nLine][nColumn], int constant) +{ + int sum = 0; + for (int line = 0; line < nLine; line = line + 1) + for (int column = 0; column < nColumn; column = column + 1) + sum = sum + a[line][column] + constant; + return sum; +} + +int main(int argc, char * argv[]) +{ + pifpii ptr; + int in0, resultH, resultS; + int constant, nLine, nColumn; + + if (argc < 3) + { + printf ("./%s \n", argv[0]); + exit(-1); + } + nLine = atoi(argv[1]); + nColumn = atoi(argv[2]); + constant = atoi(argv[3]); + + printf ("Array %dx%d. Constant Value %d\n", nLine, nColumn, constant); + int a32[nLine][nColumn]; // Create & fill the array + for (int line = 0; line < nLine; line++) + { + printf ("%d: ", line); + for (int column = 0; column < nColumn; column++) + { + a32[line][column] = line+column; + printf ("%d ", a32[line][column]); + } + printf ("\n"); + } + ptr = (pifpii) genAddArray2D (h2_malloc (1024), nColumn, constant);// Generate instructions + resultH = ptr((int *)a32, nLine, nColumn); // Call generated code + + resultS = sumArray(nLine, nColumn, a32, constant); + printf ("%d %d\n", resultH, resultS); + if (resultS == resultH) + return 0; + else + return -1; + +} diff --git a/CodeExamples/CelciusFarenheit.aarch64 b/CodeExamples/CelciusFarenheit.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..3cc903f9dd5b16ccb2d95517dd25b29752bc1661 GIT binary patch literal 48128 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/CelciusFarenheit.aarch64.c b/CodeExamples/CelciusFarenheit.aarch64.c new file mode 100644 index 0000000..f996194 --- /dev/null +++ b/CodeExamples/CelciusFarenheit.aarch64.c @@ -0,0 +1,1306 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +// X * NPowerOf2 = X >> N (immediate shift left) +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSR_3(P0, P1, P2); + } +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (aarch64)\\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genC2F(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); + tmp0001 = aarch64_genDIV_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + r = aarch64_genADD_3(r, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); + if (!r.dontFree) h2_freeReg(tmp0001.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + +h2_insn_t * genF2C(h2_insn_t * ptr) +{ + /* Code Generation of 4 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genSUB_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = aarch64_genMUL_3(tmp0000, r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); + r = aarch64_genDIV_3(r, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); + if (!r.dontFree) h2_freeReg(tmp0000.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK; + pifi fC2F, fF2C; + + resultOK = 0; + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in0 + printf("// Compilette for conversion from celcius to farenheit\n"); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fC2F = (pifi) genC2F (ptr); // + res = fC2F(in0); // Call generated code + printf("%d (celcius) -> (farenheit)%d\n", in0, res); + if (res != (in0 * 9 / 5 + 32)) + resultOK += 1; + printf("// Compilette for conversion from farenheit to celcius\n"); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fF2C = (pifi) genF2C (ptr); // + res = fF2C(in0); // Call generated code + printf("%d (farenheit) -> (celcius)%d\n", in0, res); + if (res != ((in0 - 32) * 5 / 9)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/CelciusFarenheit.power b/CodeExamples/CelciusFarenheit.power new file mode 100755 index 0000000000000000000000000000000000000000..da8d19922cdd6e1a180e5a93d5767b5a7f8aadbe GIT binary patch literal 78272 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (power)\\n"); + #endif + P2 = power_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genC2F(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x780F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); + tmp0001 = power_genDIV_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + r = power_genADD_3(r, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); + if (!r.dontFree) h2_freeReg(tmp0001.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + +h2_insn_t * genF2C(h2_insn_t * ptr) +{ + /* Code Generation of 4 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x780F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genSUB_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = power_genMUL_3(tmp0000, r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); + r = power_genDIV_3(r, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); + if (!r.dontFree) h2_freeReg(tmp0000.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK; + pifi fC2F, fF2C; + + resultOK = 0; + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in0 + printf("// Compilette for conversion from celcius to farenheit\n"); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fC2F = (pifi) genC2F (ptr); // + res = fC2F(in0); // Call generated code + printf("%d (celcius) -> (farenheit)%d\n", in0, res); + if (res != (in0 * 9 / 5 + 32)) + resultOK += 1; + printf("// Compilette for conversion from farenheit to celcius\n"); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fF2C = (pifi) genF2C (ptr); // + res = fF2C(in0); // Call generated code + printf("%d (farenheit) -> (celcius)%d\n", in0, res); + if (res != ((in0 - 32) * 5 / 9)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/CelciusFarenheit.riscv b/CodeExamples/CelciusFarenheit.riscv new file mode 100755 index 0000000000000000000000000000000000000000..27d38396a1c75b950c4aa342146d67a20fe1312b GIT binary patch literal 41504 zcmeHw4}23MWh7>O0jL;_uQGJp=|=~>wBN~ z`F$L?Gxyv%=iYnHJ@?GHcTPIbri~rV^E~G}G~ACIK?PwvcPFl;%Q!9!*E=~K*PAnN zdM=g=XE2o!4$q~6fRc!EN&=D-uoLxCiUmxG?xC3O7uaVaqaKsgtM5MHC=VkGJp-Ph0s_oH#2QUhR0bl=y<#lT;TzERSloRaU}gyYWa zmu(#PvW;iy4DM0#-Txi#1MF~6{b-(>i2H&4YepF*qDQk_a;|ksa&GqETxWco4Wq;m&d~U*Rzx=CX^VtPE zH~z~XuOI%GSO5I$ckj9G#=rEQ<2~aZVE^^Ye>RT0|Kj=u_kBq<1Rm614thmLf27Gs zLjqvBlNtd30&un1hW{Yoh5+~`z|jHt{{mPS0M7%A0j4v?<(!w=d_3U31h^ugz7)W9 z0k8@1gaCXl$Kou=%&|DEPg}Tx=}re%V6oe6cFr=x>ZF3KX_^7$*3+Q%hzH=%t*!Y{L=1zA^Gh4GVv!+=%A|ge&i%TDy zF>;hS#W?KFw(Kwv<>cC?WagR+Y^cOyk3&Z>x`F?A1_?OR_-Z&SuB1ii-iA0>AkFmGJKJE8(bi@VNC?-hXl3mGJKOu7so7!Q;xVy#M0bE8*R1 zeDFPnRdWVfI4&k^MbwjDLReWm8tSzq;7B2bpN}Lh>Vm+?PS+m2p&pY|p z1BK~&_qo~YQe#ac_~&MB{otu5V)t`5>W#(CdP!^@TI5Rbv=(ahlH7`1OW_>7QEsN( z@kY8cyf9^QTIO>z`F`QMV|Q`Uda1ZoA6E`sck7bR2qWgJfvE(w4BS$9Z{fEOP+8$$ zXH_oL)@g1kTBv>H1je zg{eialUoJJ)8dMEw-Bwi>ZMuH-SdoB!D>eD3&*3idqQ`y89X(7mj}3Fhn_7i< zvGw@VWrIESB$p0zCgM9H~ZYSo;nWpSlaCbra8@|+@F zjM#QA0_AgJKp8n|!l(i1zfXVRlj=`iu4Gtj?0jQDc*{l+SNb@y^_Qi@W#L~7k5c*K zQPk_g(d!po7{J+ ze}GpXD|%f9NY~(LJ-Q&mOV^Qwv(gq04CDB8SG>E`ID6LU^_EIb4+-y^Px^^|w@^>+ zE!?8&XM26}VXW6SrpA1g!0AiBojdCuy;MwE-a1U%0G;);G|g9~z-lAh+eU9G6wv1N z_pF+;q>|~;XYuzu^U%J#2%l=@M{g<|Ubt_#tCF9+uyP=`u(7ePf;nf`Jwx*z${XIM z9ljBxc7=FP>oa$)n$srR$DWwIeTAoF+s=w{hh|1#MqXayPMNo1-m=tL-!C51@<`V8 zjoi>*u9~x~%9YTId+B>2p%;(R8ydN9?prlSZ)oC#N)znEg7B={8Y5~=umYN_s*@3m zO@--M0~#ZirS3RNl<(IIZ};L*c5`F6>+K9aW>Gr-fwqBvWqdY&kN<~g6 zHF0xIyG#ql)Qnj?R$nxb*RRm>b1QdMF8HkGv&DNdSNVH*i@%54)gJbz9)46$JzQDu zLJ!~l9_Oz2PUvp$eki5!t=xV5UebCt1HQPBvMhDpN#ti&*4$2ZWVUvn3sT-vSZi8l zsu^?F+%>ajr9Ebe2}|3Tb}#k419o}_u!V#joGW1-=aMpbqA65q-oKYP?Lbq>Xx;|R z+n^~?Xy&Oj^$p8kCW-5dv>fEi>5Gv{kV=tOA+6S;EzeJ3>B`8&KqK_eo%EGe(!Chy zMlH)d^T^`Qpo>3kNR>>ln!+>AKbi@9d@Z^-0@~YA7vDwc6}mW(M*7Y4tWVT&9@H4V zEEOXRS-tzcs)^UPX<~aF>_q<{mG0?ZuVTOc-9)|Gnx6Hk+N*w~eebhgedO!az~H?q z?0jZ)yJss`_r!_KwykdH=91oc>=OK}%Yva7c+TKl@$=9}SRknvPkn^-;`K!$ zUsdsfr`q#!Rc+O>U4p@V3G%t*iWi#%$<*YM+)YA)r^%HdUe@b+@%q?zIDOoQoF4V) z4PSHm#P9IbZsM4vq8lUqGP$|2H@we_dIM4-QWBC8Nhe-{KXAzf+36$Xi_1*ok-r7_AE;UQdvFV+a3tWl8MjV{U4C?tR?!2}M)AN7gF=iw`y*Bd?O^|~5a zAA3y3b6)Ns6@z#VxDCK<0B!?t&ja^7aL>nR#d8a_;*a;v-cl$P)<-`s`TO3#F^ci? zi^j-B`A^XxM=pehJcp~i1p8Y=iuj>BwjlBgt$(T2?=VXL{CmLo4tQ^() z#Yw8+>!akGEF072iF|`czTwi z2him9zDchY?1}$%eZ$)2fmUwM8`RHhdqVp>0m$by;;REyNM8W)$9+JFnDZ)f-9L3fn~X%>b={eRIV_D`4NqD-)P~Yp)fS z)qWdJwJKavt+0r!))&-TyQFJ>E5ZOnak-1 z>+8Hn0_Jkvpd(kGU;a5<_rRfU%;CDj2Z-AaGe5LPU-#@+*EAE9x!e>mmz&hNj55`u zZ&K%S(}oGscmI909+ZkGH_+!UIgw%;9i91bOD}Iqv|7aL-3Sn=N;8~J<2?~!v5DS|Ac0p zpX2Dp-fYFZOSPr2`c%`_lgm=SI4Z!p;7R)nWo`P(oR~$6c(R?!9uDo=0QZVr9C`wF z@R&4#s~vR@=bCKmZEb7l{?t#bp?9nOB%cob`~v;ldQ$Bto&)R&d=34i+19gteYfoi z6+?YxPpBU1Ev>S9wzuj!``h}u`Hg|rVeLhdYKJFEr@my{(`)?stJ@UcE>wM;4NvN8 z@Wi_G{Mj@iaq?@Edp~+P<3T)sg0G%2-vd|Aihk4T+2_x-Up;>c@2v#h8&*#ObQ`N@ zZBMSAKYG(Y6K`&eWVYu9wzfM8`*R8QhgOwXHzOq>8Ig42Wq6pd7vz8H!{tkW3Kc3%zcwTYIS8x;1pq zgRfi3GhPXfJ74d1Wp&=Ab!+mu$J#8_ZR#`Rrf%#r)UEvvHv8)P3_*L>$ulIVwAAsc zSDqm)i8S-CSQFIksZ*XH^fbR>O!AZnJ%B zmtWmd`d8g`dzQgc{;#aM?|CBpQ0zhJz;9}2Vh63bnbzD_`VD<6I``J+Z&7r_KiASeYrK{miw#@oB!6HR8OsCon9!+J~KLA8w#Nd~{TR zjy{L0=2B~tgDZ_|A|`t0Nx6AqFtRnhyB`B zeHgo;p609UaWt#%YMKL9c2q{YG$>P7cFpR_uKE0gDUG zbL+UnGkd{iUkrGj#$aa#GeYqf{m;`I19qeP!;k#5{qyuT_>i8)tMs{1-Ir-p_hlN{ zzDy(AmuXb@Wg2Tgd#so}K?lJW`F6k+E8OW*6uZ5bUCM6nCAQmpiS71Yf_-?2S>a29 z!Gk?#u?f4q*mHJc&)I`LXHX@WXk8H0JMY8_2YvRy3ez6w1;q-lyobj9N-J!e8_Wvt zncYKHIFT}U=g{z{%T{utZGze70T3E)u_&@#x1Ev(;KF!jLVN&F|T5HehJ?9OvU@2sWBp-gPBzX zpRXA{Uo(8ZX83%q&{h_6L6I}e^NW<5;rSsVfq8z2T6u@XurS}SHE^{G%4T?z6mvuC zPvFCEjFQQV)Tz|5axH3-9&aSWi_?yHzYv$-ze>+#d z=GyVH-b_u1;uNicnuVqkLy|LBrDKf-p&uw5jnC7@dj zy2YSd47%4q_ZsM4!+V(}ut`f{lU`Tf%hY*igQ5X^<9!v95lIK$W0B%Sh3npO1GrAY zdmZB1C^zgN?IKy>?GKU>Ne8-Eq&Or=B>Y7AER$KJd=`+AAW-Y%2FNUy>Z;J7PYsaS zlI}=AJSW7P&bi{<=LE@f&V}(45=`e^32qw4pt2SWrg|aXUGIwb)C=gROENVG3GN11 zfdvpZ%O>B1!BtXwHD<3~0`P<_u`gK%#_ilut9saf~`vKEoszC!c}j zB!XsYFc;5sS90zjgm}*nu6XgRAeqj(B==d&mb0z|u^xR0Avw?YLcDkeI(J5p+-F>p z=L~f22UmjW2hep%a?gGW?oWgJ)8PIzxIc{=PJ{c?kf_4DMm`Nm#E~SRHIjV#3$i~% za|$%4KywN-r$BQGG^ZfZQ^1dvPcg}fGC>kSpf<>-Ah|?>Qfbzn>aOI()6luo(7Drs zq<#P5X!)A!K1??X$@bP76m3OaX6ki_p?lIc6>9O4)}-*r`Thu;JDC&2v)P@Vwy zC&2v)aDM_4Rd^4VPk?uWe1h?wD4*CzbC+n2f#w)!j)CSFXpVvA1SCrMl6*|HaK`{8 z5(LR5$;X(5Qy?Ac?B;BBpMcJtfXxLt$$i`< zd5%NpPC(~~|1Rm=18;!h2)I82?vH@`BjElRxIYGoD!liWkAU|i`3U3PC?ENn<}OLB z4m5S3sRPXs&>R8H5lEEq6XiP9&eZ`j5(LTV5@!Ggar2yXxx#m%I)Ll!8`VFkaXZb7AX!% zLNbU7=TY(@aIRB1kCp4bA)ZNI2SIZPG>1TQ2sDR4a|rSze4~6&wQ>Z-%7>WT;^afj z${qTabofwr<>o#t#Cr}y-|7U(ROgc1bvVY`gREVc1V!ihg_295cKUZ z^zCq0<(AwC-VcKJgW&xjct4054ubcCkf*}AMm`A6<46wB7)d_JcqWjt)#)V z-IbfW7W!5TefwIFOkcYs_t((3uc2==f+6OqXFv4qE9l!-g5>_nC3(JrzSTnCi2E+t zx8!P2)PVOI@LmJnYry+{@V+1NR55fm#|Gr7gd)y%$CzeyTg-Ceo4zkt4d z0e#ymNT$6m$-Ni)wio*LWoWs1_CVjNp>NfKU z5?7AlR>OCG;x~I|i%Z!(>qbfEbF0*1e&A9E5 z=5|PPJEXZC(yW3st1wO^Lxa4XNwl}T9Z(WMkf>3;#zMjoo+iP76p!7DYkUW(xXoZkq!Y@MHq#Z$ZndzglgRn$h2Uj0{ z&XsQZDNr(|Mv{zoYkkF_jSC|XAz?tmZv$NMVlzgt86$|_+ISGnDz=2?E~Hd~a)+5i zdmO$V*7a?uuXuJX#>j&)@?eZS7^CeNqwN@@?U)hD2t~>sjF3_Guo2S9+p*6PE7Q1c z1I;$jctGO;jR!Oy^qlaM_nPj&r6v=tE3i0ALSG;MPAi1}>B+oV>K|~C@>64z8 zoLC{mn<`xK?g~NjRJbH@tB_#Y>Pm2L?W*L=hlH4Cb=RShY5$|2n zxsQqaO`zHY?l*z^P2heLxZezkD!fO?o4|XbyovFiByYk#hfyY)jiA{GnvI~@2%1fx z*#wCazCqr|B-dNs2q=jlNX{s4gyeK;U9q^b+3MK@o%;uL?jM5W{)bEQ`~y0-89GPf z(xbCg{17_#A$0CTLGpa)0`JhdP0%^wr%RF>^bWY+0PZ({`wifJBe>rP?l(fB3h$Bf z2Jmi_H!$9H@z8fMx?|HlPQDpCp$v$wkTKfOIN#th|BQxeeIo zkWi*rxeuUmA3)}k2V--pJ%4~^R(NTv-g$-My@w*eaWL09Fr z{1x!N4!oCx_j2%F4&KXAOF87JaLzH#V@VFsnK-!|`y7%?@>&O)b)Z=XnsuOA2by(| z=Q<{-bxdv=nV>is5U3@29kX)lu;x!hnWAs&p>O5Tw{k&pm%AiSIrQy)=-c}}EjMu; z^lcsVZJi)_*105cJ@joo^lg1tR!@LmSq%fNdXsLQ~68F(*)Jj)p8qFe^fB^eMn zH^^m-XQEjHnl+$V1DZ9USp%9ikSF2C$!i#OxV#3Cfgn&P%4?X7TLU|3M46&*Wze@W z=v$c}iSM~2(|gdj_n>d@^|ajFYoKpypl@ph$+Xrbxz|G9)g70x5%)!;l)Ud=d9l2;!mo{44^XjXw{6=+t0W;JM5L!N|hkXJFe z^_EuwN+JkyGs>%&gJyeWNkyS^M^P=-c0+ zZ+{mg&);3(9Qw8z`bOMzNp5}r3EoS=dntG?1@EiC`zr9h3i4DqkCaQnxlt}Xi7m-3Yt>%fbf+=7Oxdf0-rH++LnSCq8K8J)dMc>|mzP$r| zdq+T&94OS#o)aJyqAFY z67XJvT1p^Kg>#N^9!qk7#>B}b*yoUBl2MHLKtfW;Gt>wn=tuHhGQ^4<~ z^((%8UU+-N^YnJTzU+ZhiL=+t7FN!h=UTaS-Y{)R>b-M^-5t)apR*x#{cP=s4gPoT z6emu91HtoVec9pD=*^qM3-K$lsrZ%HRK!T+bQ&o^vTlZ~e~y%3zhhPPtkXydfyTEj z;-PH$?jR8lWzTM^FI!G43>g~TX=DYP$1-azT&DO317aIUtNrm6fLdT-DdOSHpjsW& zt_P(EwVsusJ2EWc1wk@ha7pe9;P?V8A^qAn=={NYb}4oP=)L`Nb-$uwPb2sa8tuWj z?hxmJodCpnprxRZ5==^nYCud%hj}=AA1be4)!Wsd=rve4$1jqMJl{IFdu`)d@$ZSM0;Q-0MQ

&&A|66SN&w$L5faSKQT#(dyacmz$FLI+i};al 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/CelciusFarenheit.riscv.c b/CodeExamples/CelciusFarenheit.riscv.c new file mode 100644 index 0000000..2bf1682 --- /dev/null +++ b/CodeExamples/CelciusFarenheit.riscv.c @@ -0,0 +1,902 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genC2F(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x73F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}, immValueZero); + tmp0001 = riscv_genDIV_4(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}, immValueZero); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + r = riscv_genADD_3(r, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); + if (!r.dontFree) h2_freeReg(tmp0001.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + +h2_insn_t * genF2C(h2_insn_t * ptr) +{ + /* Code Generation of 4 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x73F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genSUB_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = riscv_genMUL_4(tmp0000, r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}, immValueZero); + r = riscv_genDIV_4(r, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}, immValueZero); + if (!r.dontFree) h2_freeReg(tmp0000.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, res, resultOK; + pifi fC2F, fF2C; + + resultOK = 0; + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in0 + printf("// Compilette for conversion from celcius to farenheit\n"); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fC2F = (pifi) genC2F (ptr); // + res = fC2F(in0); // Call generated code + printf("%d (celcius) -> (farenheit)%d\n", in0, res); + if (res != (in0 * 9 / 5 + 32)) + resultOK += 1; + printf("// Compilette for conversion from farenheit to celcius\n"); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fF2C = (pifi) genF2C (ptr); // + res = fF2C(in0); // Call generated code + printf("%d (farenheit) -> (celcius)%d\n", in0, res); + if (res != ((in0 - 32) * 5 / 9)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Constants-Operations.aarch64 b/CodeExamples/Constants-Operations.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..afcc3ff66831d5d73e2e15206de644962ccecab3 GIT binary patch literal 52312 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +// X * NPowerOf2 = X >> N (immediate shift left) +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSR_3(P0, P1, P2); + } +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (aarch64)\\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} + +/* End Header autogenerated part */ +#include // -*- c -*- +#include + +typedef int (*pifi)(); + +pifi genConstAdd(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genADD_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstSub(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genSUB_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstMul(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genMUL_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstDiv(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genDIV_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +int main(int argc, char * argv[]) +{ + int in0, res; + int isOK = true; + pifi fPtr; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in0 + fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions + + printf("// Compilette for simple addition between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstAdd (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d + %d = %d\n", 42, in0, res); + isOK &= (res == (42+in0)); + + printf("// Compilette for simple substraction between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstSub (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d - %d = %d\n", 42, in0, res); + isOK &= (res == (42 - in0)); + + printf("// Compilette for simple multiplication between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstMul (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d * %d = %d\n", 42, in0, res); + isOK &= (res == (42 * in0)); + + printf("// Compilette for simple division between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstDiv (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d / %d = %d\n", 42, in0, res); + isOK &= (res == (42 / in0)); + + return isOK?0:1; +} diff --git a/CodeExamples/Constants-Operations.power b/CodeExamples/Constants-Operations.power new file mode 100755 index 0000000000000000000000000000000000000000..24b1682f4dcd421f03e8efae3b955c4c93e19474 GIT binary patch literal 78360 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Constants-Operations.power.c b/CodeExamples/Constants-Operations.power.c new file mode 100644 index 0000000..2520381 --- /dev/null +++ b/CodeExamples/Constants-Operations.power.c @@ -0,0 +1,1067 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (power)\\n"); + #endif + P2 = power_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +#include // -*- c -*- +#include + +typedef int (*pifi)(); + +pifi genConstAdd(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genADD_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstSub(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genSUB_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstMul(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genMUL_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstDiv(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genDIV_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +int main(int argc, char * argv[]) +{ + int in0, res; + int isOK = true; + pifi fPtr; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in0 + fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions + + printf("// Compilette for simple addition between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstAdd (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d + %d = %d\n", 42, in0, res); + isOK &= (res == (42+in0)); + + printf("// Compilette for simple substraction between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstSub (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d - %d = %d\n", 42, in0, res); + isOK &= (res == (42 - in0)); + + printf("// Compilette for simple multiplication between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstMul (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d * %d = %d\n", 42, in0, res); + isOK &= (res == (42 * in0)); + + printf("// Compilette for simple division between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstDiv (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d / %d = %d\n", 42, in0, res); + isOK &= (res == (42 / in0)); + + return isOK?0:1; +} diff --git a/CodeExamples/Constants-Operations.riscv b/CodeExamples/Constants-Operations.riscv new file mode 100755 index 0000000000000000000000000000000000000000..0f07a2cf7ee2eddc93ad8b5b12d29f01682cc510 GIT binary patch literal 53860 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Constants-Operations.riscv.c b/CodeExamples/Constants-Operations.riscv.c new file mode 100644 index 0000000..8d7de02 --- /dev/null +++ b/CodeExamples/Constants-Operations.riscv.c @@ -0,0 +1,1025 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} + +/* End Header autogenerated part */ +#include // -*- c -*- +#include + +typedef int (*pifi)(); + +pifi genConstAdd(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x33F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genADD_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstSub(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x33F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genSUB_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstMul(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x33F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genMUL_4(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +pifi genConstDiv(pifi ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x33F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genDIV_4(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (pifi) ptr; +} + +int main(int argc, char * argv[]) +{ + int in0, res; + int isOK = true; + pifi fPtr; + + if (argc < 2) + { + printf("Give 1 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in0 + fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions + + printf("// Compilette for simple addition between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstAdd (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d + %d = %d\n", 42, in0, res); + isOK &= (res == (42+in0)); + + printf("// Compilette for simple substraction between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstSub (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d - %d = %d\n", 42, in0, res); + isOK &= (res == (42 - in0)); + + printf("// Compilette for simple multiplication between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstMul (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d * %d = %d\n", 42, in0, res); + isOK &= (res == (42 * in0)); + + printf("// Compilette for simple division between constants\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = genConstDiv (fPtr, in0); // Generate instructions + res = fPtr(); // Call generated code + printf("%d / %d = %d\n", 42, in0, res); + isOK &= (res == (42 / in0)); + + return isOK?0:1; +} diff --git a/CodeExamples/If-in-Loop.aarch64 b/CodeExamples/If-in-Loop.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..7d24abd538baab0e56deefcc7b83b7db5c559bfe GIT binary patch literal 52344 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 a12(Q7{fz-yqVi?0i1PIAhJM5)+5Z4W)Ije5 literal 0 HcmV?d00001 diff --git a/CodeExamples/If-in-Loop.aarch64.c b/CodeExamples/If-in-Loop.aarch64.c new file mode 100644 index 0000000..03a600b --- /dev/null +++ b/CodeExamples/If-in-Loop.aarch64.c @@ -0,0 +1,1471 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_NE_I_I_64_1(i0) do /* bne */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0x1 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_GE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_NE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +// X * NPowerOf2 = X >> N (immediate shift left) +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSR_3(P0, P1, P2); + } +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (aarch64)\\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +/* C compilette prototype */ +h2_insn_t * genIf(h2_insn_t * ptr) +{ + /* Code Generation of 22 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_endtrue_00000001 */ + #define h2_endtrue_00000001 1 + 0, /* h2_iffalse_00000002 */ + #define h2_iffalse_00000002 2 + 0, /* h2_ifend_00000003 */ + #define h2_ifend_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0F01, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, LoopValue); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0002 = aarch64_genDIV_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + reste = aarch64_genMUL_3(reste, tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + if (!reste.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, reste); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_endtrue_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_iffalse_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_ifend_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; + aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_endtrue_00000001]; + aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int selected, res; + int i, tmp; + pifi iPtr; + + if (argc < 2) + { + printf("Give 2 value (LoopValue)\n"); + exit(-1); + } + selected = atoi (argv[1]); // Get threshold value + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifi) genIf (ptr); // Generate instructions + res = iPtr(selected); // Call generated code + printf ("Result %d : %d\n", selected, res); + for (i = 0; i < selected; i = i + 1) + { + if (i % 2) tmp = tmp + i; + } + + return tmp == res; +} diff --git a/CodeExamples/If-in-Loop.power b/CodeExamples/If-in-Loop.power new file mode 100755 index 0000000000000000000000000000000000000000..5f619834866535b5ae37302561bb6082b91ecbfe GIT binary patch literal 78384 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/If-in-Loop.power.c b/CodeExamples/If-in-Loop.power.c new file mode 100644 index 0000000..8eabc2a --- /dev/null +++ b/CodeExamples/If-in-Loop.power.c @@ -0,0 +1,1172 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_BNE_I_I_32_1(i0) do /* bne */ { power_G32(((0x4082 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBNE_1(h2_sValue_t P0); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genBGE_1(h2_sValue_t P0); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBNE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BNE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BGE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (power)\\n"); + #endif + P2 = power_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +/* C compilette prototype */ +h2_insn_t * genIf(h2_insn_t * ptr) +{ + /* Code Generation of 22 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_endtrue_00000001 */ + #define h2_endtrue_00000001 1 + 0, /* h2_iffalse_00000002 */ + #define h2_iffalse_00000002 2 + 0, /* h2_ifend_00000003 */ + #define h2_ifend_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1F80F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, LoopValue); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0002 = power_genDIV_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + reste = power_genMUL_3(reste, tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + if (!reste.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, reste); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_endtrue_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_iffalse_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_ifend_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; + power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_endtrue_00000001]; + power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int selected, res; + int i, tmp; + pifi iPtr; + + if (argc < 2) + { + printf("Give 2 value (LoopValue)\n"); + exit(-1); + } + selected = atoi (argv[1]); // Get threshold value + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifi) genIf (ptr); // Generate instructions + res = iPtr(selected); // Call generated code + printf ("Result %d : %d\n", selected, res); + for (i = 0; i < selected; i = i + 1) + { + if (i % 2) tmp = tmp + i; + } + + return tmp == res; +} diff --git a/CodeExamples/If-in-Loop.riscv b/CodeExamples/If-in-Loop.riscv new file mode 100755 index 0000000000000000000000000000000000000000..5080de950997ddccad7c7f5fe307bc927d298bbd GIT binary patch literal 41564 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_BNE_RRI_I_32_1(r1,r2,i1) do /* BNE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BNE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +/* C compilette prototype */ +h2_insn_t * genIf(h2_insn_t * ptr) +{ + /* Code Generation of 20 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_endtrue_00000001 */ + #define h2_endtrue_00000001 1 + 0, /* h2_iffalse_00000002 */ + #define h2_iffalse_00000002 2 + 0, /* h2_ifend_00000003 */ + #define h2_ifend_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7FF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGE_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0002 = riscv_genDIV_4(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, immValueZero); + reste = riscv_genMUL_4(reste, tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, immValueZero); + if (!reste.dontFree) h2_freeReg(tmp0002.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBNE_3(i, reste, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_endtrue_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_iffalse_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_ifend_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000005]; + i = riscv_genBGE_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_prologue_00000000]; + i = riscv_genBNE_3(i, reste, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_endtrue_00000001]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int selected, res; + int i, tmp; + pifi iPtr; + + if (argc < 2) + { + printf("Give 2 value (LoopValue)\n"); + exit(-1); + } + selected = atoi (argv[1]); // Get threshold value + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifi) genIf (ptr); // Generate instructions + res = iPtr(selected); // Call generated code + printf ("Result %d : %d\n", selected, res); + for (i = 0; i < selected; i = i + 1) + { + if (i % 2) tmp = tmp + i; + } + + return tmp == res; +} diff --git a/CodeExamples/If.aarch64 b/CodeExamples/If.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..2f4562fca1e54a3befcfe92f377923e76ac5ab8c GIT binary patch literal 44024 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/If.aarch64.c b/CodeExamples/If.aarch64.c new file mode 100644 index 0000000..e3f6f2c --- /dev/null +++ b/CodeExamples/If.aarch64.c @@ -0,0 +1,1117 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_NE_I_I_64_1(i0) do /* bne */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0x1 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_NE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +/* C compilette prototype */ +h2_insn_t * genIf(h2_insn_t * ptr, int selectedValue) +{ + /* Code Generation of 12 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t value = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t threshold = {H2REGISTER, 'i', 1, 31, 10, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 31, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_endtrue_00000001 */ + #define h2_endtrue_00000001 1 + 0, /* h2_iffalse_00000002 */ + #define h2_iffalse_00000002 2 + 0, /* h2_ifend_00000003 */ + #define h2_ifend_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0701, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + threshold = aarch64_genMV_3(threshold, (h2_sValue_t) {H2VALUE, 'i', 1, 31, 0, (int)((selectedValue))}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + value = aarch64_genCMP_2(value, threshold); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_endtrue_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_iffalse_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_ifend_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; + aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_endtrue_00000001]; + aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int selected, toTest, res; + pifi iPtr; + + if (argc < 2) + { + printf("Give 2 value (testValue, testedValue)\n"); + exit(-1); + } + selected = atoi (argv[1]); // Get threshold value + toTest = atoi (argv[2]); // Value to be tested + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifi) genIf (ptr, selected); // Generate instructions + res = iPtr(toTest); // Call generated code + printf ("Result %d = %d : %d\n", selected, toTest, res); + return res; +} diff --git a/CodeExamples/If.power b/CodeExamples/If.power new file mode 100755 index 0000000000000000000000000000000000000000..c5bbf4e813375810a588d6bcb1084fa5896efdb1 GIT binary patch literal 78264 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 Q^+8deUTHO7Nm=&)0PCebUjP6A literal 0 HcmV?d00001 diff --git a/CodeExamples/If.power.c b/CodeExamples/If.power.c new file mode 100644 index 0000000..41cb10b --- /dev/null +++ b/CodeExamples/If.power.c @@ -0,0 +1,936 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_BNE_I_I_32_1(i0) do /* bne */ { power_G32(((0x4082 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBNE_1(h2_sValue_t P0); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBNE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BNE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +/* C compilette prototype */ +h2_insn_t * genIf(h2_insn_t * ptr, int selectedValue) +{ + /* Code Generation of 12 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t value = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t threshold = {H2REGISTER, 'i', 1, 31, 15, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 31, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_endtrue_00000001 */ + #define h2_endtrue_00000001 1 + 0, /* h2_iffalse_00000002 */ + #define h2_iffalse_00000002 2 + 0, /* h2_ifend_00000003 */ + #define h2_ifend_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF80F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + threshold = power_genMV_2(threshold, (h2_sValue_t) {H2VALUE, 'i', 1, 31, 0, (int)((selectedValue))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + value = power_genCMP_2(value, threshold); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_endtrue_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_iffalse_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_ifend_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; + power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_endtrue_00000001]; + power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int selected, toTest, res; + pifi iPtr; + + if (argc < 2) + { + printf("Give 2 value (testValue, testedValue)\n"); + exit(-1); + } + selected = atoi (argv[1]); // Get threshold value + toTest = atoi (argv[2]); // Value to be tested + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifi) genIf (ptr, selected); // Generate instructions + res = iPtr(toTest); // Call generated code + printf ("Result %d = %d : %d\n", selected, toTest, res); + return res; +} diff --git a/CodeExamples/If.riscv b/CodeExamples/If.riscv new file mode 100755 index 0000000000000000000000000000000000000000..62e286418223b85232c55e7190ee2e47f770e5dc GIT binary patch literal 33272 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_BNE_RRI_I_32_1(r1,r2,i1) do /* BNE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BNE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +/* C compilette prototype */ +h2_insn_t * genIf(h2_insn_t * ptr, int selectedValue) +{ + /* Code Generation of 11 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t value = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t threshold = {H2REGISTER, 'i', 1, 31, 6, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 31, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_endtrue_00000001 */ + #define h2_endtrue_00000001 1 + 0, /* h2_iffalse_00000002 */ + #define h2_iffalse_00000002 2 + 0, /* h2_ifend_00000003 */ + #define h2_ifend_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x77F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + threshold = riscv_genMV_2(threshold, (h2_sValue_t) {H2VALUE, 'i', 1, 31, 0, (int)((selectedValue))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + value = riscv_genBNE_3(value, threshold, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_endtrue_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_iffalse_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_ifend_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_prologue_00000000]; + value = riscv_genBNE_3(value, threshold, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_endtrue_00000001]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int selected, toTest, res; + pifi iPtr; + + if (argc < 2) + { + printf("Give 2 value (testValue, testedValue)\n"); + exit(-1); + } + selected = atoi (argv[1]); // Get threshold value + toTest = atoi (argv[2]); // Value to be tested + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifi) genIf (ptr, selected); // Generate instructions + res = iPtr(toTest); // Call generated code + printf ("Result %d = %d : %d\n", selected, toTest, res); + return res; +} diff --git a/CodeExamples/Loop-in-If.aarch64 b/CodeExamples/Loop-in-If.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..3df33b82cdd3b6517771f56b22b17b0e27196c6f GIT binary patch literal 52312 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Loop-in-If.aarch64.c b/CodeExamples/Loop-in-If.aarch64.c new file mode 100644 index 0000000..4eaf1ce --- /dev/null +++ b/CodeExamples/Loop-in-If.aarch64.c @@ -0,0 +1,1439 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_GT_I_I_64_1(i0) do /* bgt */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xc & 0x1f) >> 0)); } while(0); +#define A64_B_NE_I_I_64_1(i0) do /* bne */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0x1 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genBGT_1(h2_sValue_t P0); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_NE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genBGT_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGT instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGT + +// No specific optimisation for BGT/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_GT_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BGT instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifii)(int, int); + +/* C compilette prototype */ +h2_insn_t * genPlusOrMul(h2_insn_t * ptr) +{ + /* Code Generation of 32 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t plus = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + 0, /* h2_prologue_00000008 */ + #define h2_prologue_00000008 8 + 0, /* h2_endtrue_00000009 */ + #define h2_endtrue_00000009 9 + 0, /* h2_iffalse_00000010 */ + #define h2_iffalse_00000010 10 + 0, /* h2_ifend_00000011 */ + #define h2_ifend_00000011 11 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0F03, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000008); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + plus = aarch64_genCMP_2(plus, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, LoopValue); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genMUL_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_endtrue_00000009); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_iffalse_00000010); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, LoopValue); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_ifend_00000011); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_prologue_00000008] + 1; + aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_endtrue_00000009]; + aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int plus, loopValue, res; + int i, tmp; + pifii iPtr; + + if (argc < 2) + { + printf("Give 2 values (Plus LoopValue)\n"); + exit(-1); + } + plus = atoi (argv[1]); // Get operator + = 1, other = * + loopValue = atoi (argv[2]); // Get threshold value + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifii) genPlusOrMul(ptr); // Generate instructions + res = iPtr(plus, loopValue); // Call generated code + if (plus == 1) + for (tmp = 1, i = 1; i <= loopValue; i = i + 1) + { + tmp *= i; + } + else + for (tmp = 0, i = 1; i <= loopValue; i = i + 1) + { + tmp += i; + } + printf ("Result plus = %d, loopValue %d : %d (%d)\n", plus, loopValue, res, tmp); + return tmp != res; +} diff --git a/CodeExamples/Loop-in-If.power b/CodeExamples/Loop-in-If.power new file mode 100755 index 0000000000000000000000000000000000000000..1b3810cab7df8590800027ff37bb0de7ca07b409 GIT binary patch literal 78352 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 ML9fbM58JKyZ<$W?E&u=k literal 0 HcmV?d00001 diff --git a/CodeExamples/Loop-in-If.power.c b/CodeExamples/Loop-in-If.power.c new file mode 100644 index 0000000..63df0f3 --- /dev/null +++ b/CodeExamples/Loop-in-If.power.c @@ -0,0 +1,1164 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_BGT_I_I_32_1(i0) do /* bgt */ { power_G32(((0x4181 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_BNE_I_I_32_1(i0) do /* bne */ { power_G32(((0x4082 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBNE_1(h2_sValue_t P0); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBGT_1(h2_sValue_t P0); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBNE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BNE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBGT_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGT instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGT + +// No specific optimisation for BGT/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BGT_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BGT instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifii)(int, int); + +/* C compilette prototype */ +h2_insn_t * genPlusOrMul(h2_insn_t * ptr) +{ + /* Code Generation of 32 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t plus = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + 0, /* h2_prologue_00000008 */ + #define h2_prologue_00000008 8 + 0, /* h2_endtrue_00000009 */ + #define h2_endtrue_00000009 9 + 0, /* h2_iffalse_00000010 */ + #define h2_iffalse_00000010 10 + 0, /* h2_ifend_00000011 */ + #define h2_ifend_00000011 11 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1F81F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000008); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + plus = power_genCMP_2(plus, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, LoopValue); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genMUL_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_endtrue_00000009); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_iffalse_00000010); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, LoopValue); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_ifend_00000011); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_prologue_00000008] + 1; + power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + power_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_endtrue_00000009]; + power_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + power_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int plus, loopValue, res; + int i, tmp; + pifii iPtr; + + if (argc < 2) + { + printf("Give 2 values (Plus LoopValue)\n"); + exit(-1); + } + plus = atoi (argv[1]); // Get operator + = 1, other = * + loopValue = atoi (argv[2]); // Get threshold value + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifii) genPlusOrMul(ptr); // Generate instructions + res = iPtr(plus, loopValue); // Call generated code + if (plus == 1) + for (tmp = 1, i = 1; i <= loopValue; i = i + 1) + { + tmp *= i; + } + else + for (tmp = 0, i = 1; i <= loopValue; i = i + 1) + { + tmp += i; + } + printf ("Result plus = %d, loopValue %d : %d (%d)\n", plus, loopValue, res, tmp); + return tmp != res; +} diff --git a/CodeExamples/Loop-in-If.riscv b/CodeExamples/Loop-in-If.riscv new file mode 100755 index 0000000000000000000000000000000000000000..c7374d89b230df7d3a738d6bd8dadf608f2156ca GIT binary patch literal 41540 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 W%B2=fr!2mFQ{Y^NshP-AqyG +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_BNE_RRI_I_32_1(r1,r2,i1) do /* BNE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_BGT_RRI_I_32_1(r2,r1,i1) do /* BGT */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBGT_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBGT_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGT instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGT + +// No specific optimisation for BGT/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BGT_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BGT instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BNE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BNE + +// No specific optimisation for BNE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BNE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BNE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifii)(int, int); + +/* C compilette prototype */ +h2_insn_t * genPlusOrMul(h2_insn_t * ptr) +{ + /* Code Generation of 29 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t plus = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + 0, /* h2_prologue_00000008 */ + #define h2_prologue_00000008 8 + 0, /* h2_endtrue_00000009 */ + #define h2_endtrue_00000009 9 + 0, /* h2_iffalse_00000010 */ + #define h2_iffalse_00000010 10 + 0, /* h2_ifend_00000011 */ + #define h2_ifend_00000011 11 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000008); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + plus = riscv_genBNE_3(plus, tmp, intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genMUL_4(tmp, tmp, i, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_endtrue_00000009); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_iffalse_00000010); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, i); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_ifend_00000011); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_prologue_00000008]; + plus = riscv_genBNE_3(plus, tmp, intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000001]; + i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_endtrue_00000009]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000005]; + i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int plus, loopValue, res; + int i, tmp; + pifii iPtr; + + if (argc < 2) + { + printf("Give 2 values (Plus LoopValue)\n"); + exit(-1); + } + plus = atoi (argv[1]); // Get operator + = 1, other = * + loopValue = atoi (argv[2]); // Get threshold value + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + iPtr = (pifii) genPlusOrMul(ptr); // Generate instructions + res = iPtr(plus, loopValue); // Call generated code + if (plus == 1) + for (tmp = 1, i = 1; i <= loopValue; i = i + 1) + { + tmp *= i; + } + else + for (tmp = 0, i = 1; i <= loopValue; i = i + 1) + { + tmp += i; + } + printf ("Result plus = %d, loopValue %d : %d (%d)\n", plus, loopValue, res, tmp); + return tmp != res; +} diff --git a/CodeExamples/Loop.aarch64 b/CodeExamples/Loop.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..ffc1bf970ff29a20201ed1a4db9ec15f29e75c40 GIT binary patch literal 44024 zcmeHwdwi7Dng4m;cW${~22!G1q6@$h-OV#9oi4ykrAk6d?XpfJZdnp(v{e*U z%6Mg! zlm+5JxXRDS_QZ$uoQq!`ek3COh=%aF9)zG=dV()~=gt{OvL1w9nxU3>WrAOw1-?8B z{F*HAbF;ud2e^q}`Y{cFO!AQaGQs~g3*5{CCmxyjT#yA`2Y3ma!nSnOASdj?GyW}s zDC_Wt!=W(i=!{0_)Y$3^Ghag}jGAyD7;R=P{%D7<#UBaW;%Dt0;ZW4y7-j9gwzg0s zi$t41&YEuu2cmxFi-rQsMV4mkOi zI$RdGYMbhcEpYO8bxg6q)mW!G(*n1~!}%6C9|w}rLJQm~{}Kya#V#UoTi`T4)p5B6 zPUBA<>n(5^lj_)Hfzw!5ht~qPj(yKuaz&o33-AnFb< zcDUp(tA~n@uIM)PS-+fR8n37y>IO@6_fWCUcpWc0P@Zim=b~I|DHo#LU@4cPe5<8A z3FU_^iu3+r#eoSi>ps6t3Lq5<9 z8rpsayAWMEKJZ?e{qgpfYw~y8S@Chr?t{Re4cgkd?x6-wt0!ow&68XIo%_POd2HxA zXw$3LF70CM({DgdlXca5b$#i(dG4W;Tc6{8@)qQc?_@uZ6|uhfEY^oHQy!b;?!)*j ziJ=@TLVlZ8M)j1R#n@&o9^Xhfpz9`?RhxuAFdcZ)1s(=6$J2=(Fz~#3z+ekvhQ8ok z$iv$~_#~cQ=%nA?RgW=V-tX$FCp?q%>ejlq16TA-$b53^zwtgorlEn!tnX+U+BCZA zW9K3*bN9vO09NEiox6|o@M_&bYVTasRkOZ1Xya%#@`vuK??3cp*uBlXpMC6oS=*+U zxwp+KgU;8+3~d36&fI`#l*hKr+E4=+Y`6I!^$D~Cpgjm$ZCl0t6`-vEEdwpuTbq!* zN9$gXc1fpPj()9s9mxTD(gn#vdFuZcKZ=_&edQ$QdE=Lpw}rMB5iij5 zw!n|_)Ydi`$KCf8D>cG z?mmrK%6TZ;EM+IkE=$=!IiK|rfAHnLL%eji-mQ2to4eO-W4(l9^(|fxJVe?)^0PSn zY%=s?^`U*Rjl$Ci4?Z^=KJPaBr@^KRl6BAp>Pi$n`6v0h@X?Z(^5Jc4a}IQ6k{`yj z?pOZ8$NC^M^={~KDPvuwY8Bj2nZ!Bx%1GD@)~d6#7K{evGrBeW0WM^keLzox{wlcXtpk=;a@g zsy0GsgSQR6!G6#it7kLBxbITBfPPUo1pnHv+q!;Hf%wdMLf)<5)dilPq4s!;6TX>< zJBR}$?`Ki3>~V7I4@Df@p!L3Ixc0vbzFuAE{~+Y`mLhLsi+sqpz~{ZCtPilIvmVtp z!-qF|3kg@-{G@?=F2~(mLwVw1W19zbvTh%=_W+lRjV4l&G!el$S-M#%c#km0w8y>9`2%y2F^3Y}=MC+F+7 zch3Xgz5m2|_vW&pz0(+CXIFifjOWA0^E^XAsHs3{gX`>3tD;}_; z;^#xYN7|0;+XH>D<;5Gc@?zNUEA`B~KU@JDQk$%G`UX}!y_Cvmua6b8(k%8pTrteP zlSZ`f?_s0U?gPdg?*qw3eJG|r+*Z#vJu;R)9L5!*)knwOhi5YN0b}L#?XVYi_`zA} z!xtx_4_WQ-owL%1&x-MWfc4nBt4_*wXfjqDV2Bm-0axQe#tJO)6R`p~(Lu1hE?FlR_^$_MBMZ4 zudkqa3%EzIes%+wZJe}$EeG!CvGBCx$cLH6;CSPCrZLFQUM&2vr4I?4Ar_vp&2a6L zuvt0mfM1HuT7QtVne*)1?2N@tZnLu-H@%MT*hiV;=C1+wjuMB)xyIu0?GX5Ojl%a- z;^z0MAEWR+mAKghz7rESzm>8sd>`w=_ptta7wf_gXk94R-W3%0s2_-92NB=m+w*$k zjch3Xl34r2Ue=e=S}*nt%8385XIbA(i0!fGaZR{Ar#HRvgo-Jy4gO{wS~4x~ZMx;B%de?NRnm zp95B*AAAmwcBFdfB{4@_ih8eQj?ieW3mwcd+2$wdnuXTD$k$lby|`9O%ojV5r#Xk# zw;I;BjD5MDb?xJ86>5iJevs?jF~s(BMqKCqqn=#nW|Y%CUO9Wuh@9?BazeIK(q|Xx z^UTOOX*4;D$DvOy=b5ql@3jne@3QD~JaRHzmz^PfK9@;Oy53jg$Tc2)lALEopZ8hh z9I%Y{^lPm|Od)FJq}jd93r;y7CR0SzgMzy6PGGIv-OiCSvcti zh41&l_gU<3Jd6E}XXXAzkKEtrk^37xa(|;o?r#8Y+28ot@cj+!{nI*~_ReYlR>_^d zF1>eX6J?{A zE$(6Lw0%6`A2Db5rY!zZKY@0%`o~J}RsGK9A7k}9tAA9Tj(^}@kJ|qlNx#|_+#7o7 z2VspdevePwzw1l6?n}QP&?DC;+{Q9rBkaxZ#n6409_cqbkiQLi+DoK8McPlKy(=&F zt*qCmb1*KRhwmRVYzv-;?>`5>KM0?Po=XqH=ldtoJ{;DmavY}n^D(k5@VYGZ6qD3m z-EYW7mg}%YEH^Fd0pu&l&lL}gKl_mHk#LRj*7ZQwu6p*uV-vI<82Mhr3d=P`#y+@D zrw`vaD}5-;)Cb6&SeKoS9S)tHKD?f3U1seAu9;5RmkymBUwYEghl47T*iRV`-d-N-Y5a|FUv3OBf8?>SZ6f4HAG!Q=orQgL?fgll%oKa< zXIlPs7Worn8TwC*1FVZr*@upt9Uq!LS|3hl92_}2WBGqZTOXf}9bP*-eZb~u;vRKk zEMu)UuCbhPEQos-XL>CB^F+wc~gV(b1k;A(9_>qL&v#C=_!$MwlruOl?9mpBcsPaXx|F1a?z#&>{oeO<+O3;0^se)NpW`0nfe$MEYOJhx)K?&0?*)H*J0Pkz$} zBd-0YeG{-Av z#y!!~meY|*PUtYPcPsap$D~i%3%}#c$oZOOK1=A+D(86g$>lsVcK>!JIlCT##@Fe~|IM=^zjZG=p?{3K)0h9Lvm*banbuiW`4KmG+>>)z z`ZeD$|8bXW(594>vilx8EAo$ZFI$b%gO+PnAM#v&mgSz#U1QqIKJB@X_9_{z6}>s# zmG5R=E1nCu>O;0Q-Kne>`?t=AP@JL}mIF&B+;ZFJiH@`z>aG(hsvS`=gUF3QV& z_zKEPyB@TxMSbaOQS)IwPQBEZ67x9i%9k^+JD(* zFXQ)EUG!`;u5V&ezf@@Rl6we zTlN|d+Xsj5HH^H5+B=$@&{>To9*lTxigA|7<`W@j=V)?{OP?g?@N2$_kaMj?&V+B$ zJ$};RxZ~@$hsD>4ka6~@%9wHdh&?^)_?ZY9hb(K$#Q3pZLyglf*}>tlXd>kN*=TZ( z(=X4|IM4X(iD|h%fP4kbuWH^`b1K%iKIHo)T%-K3wTqme2%cqrnh0HIT(7$)st=>D zzb2v&a=m_-nYrCHgIGsW3{URu0&eSG2Dn$PZN$3zuzL1{(R-HT-`hP*&z@9Ld!z6j z=X#y&-#w%9`Nh3@Z&a-{Ai75<=2zocTQG*BR$J-fP86$YnjK%CoI=818TiJj@ZEU zfjB|20eVV4+sL0~n5ft=@;#F?`z*sm#fFjlaAu!nI6Hkfv(GY|9bcM|XBlWb<9eCm zL-JVwalMSOf12~;$bK{-&oW>BEFP%aCy_d}}OY0qeHpvjDh0ANRZV6Y?xW##kh-Ek}t(r!BvHmf--4<#ylx zzkI!m^=sl;h6A+T-43`nbzOSEvfc&GxSwS>KBHpR zH@;^XINw#^Yh9b3`m+pU|MtoJKZy0ASFJ~}hEv}@`90<@wP&$|@^alG+8>@n?~K#+$*4X*`ZrJ*J;&XX*L~vmnSJIRz_~mao7rsOlQ!^Se{i&Kpz!wK zGjD|z7oh#~xiz41GNKV9ONN&GyCUnKF%WICDXT%arLjc*0rN4jh$Pqg#4F53Ac z;MC5Cy2Q`#jo$$L-$?v2iT{$s{~6%0FW$QqbiYz`xxMl0K=+KK+np=gc|y{CQ|}|c zhV=+8@<@Q0sicyD@I zZ~QmFeMaIwB5`*+1nv_O_nSybSKraZd(%eVDDO=>v)9vm(K{Vk>#griA45CG4P$>k z-XnQW#RJ3`4d06*-I1>T0C;@+lwQ0i4&Rdf*s1y~`*El2$5*J&lX~ON0C%gzZB%`> zi$32VaYM4t5$ZF^oSRi<@veCGKJjXZX*z z0OxIvBopy8^0T%%fO_IV`aX{L@EPuH#=vg?w6cGsXAGcE_$oJ>(cLvg?P}b2+vBtMNUk&8q(+`62KBNPbE- z&90xLb*Ps*I>y^J_Fsch~=9ADLWw*q*L(D4X{Vc{@g?>(#{V-%d%Va%178>z$?wRQcjDV`S-$gjle1C(>wOf9l1K;i7 za(z?E^&Kf!Ha~ev%C$55_cyF^eWY~B^_ME!e$-j#R*Fp(h)rCta;{Z6raHonVV-`N z?1l8?R(CJfee!##V*Sm(hnfdF(RUwlALx+S%Rj)p`Q5euBfgVpB8}l&jLf9(&$@@^ zQh5dXMKHI3%_7(`=%lOb7td3B)4_APd#IW8Jedt0rEfMabN9toxcl5}#V_eQsK@YK z&!d110LEx7-JjoG2|iSg0d8(%(+7aFg0UNXTrTnLRq}uJEx%d#)*^kolv4G(9qao? z4&&WBd{cHdTlUH^d{6MsRlEp~Cky7e#LhPB9T=5y0-#rI8hHv5YnroDX>{BOhe zC5gxEt$DB1GTWUinEv+T_>Sz}WyUKHgWpl@_{EL+tn^mU*O|{xYXCh1eFNwqZ-wLIA>vtdbpx=9*ySSUaLwGmx-+TDt?mhZBFMWV-VSdYYE0Q5agg6n-j6-~1zzZOuU__c z1>~l09@2NgK5VQ@eEX2-=$%K8<(tgvd(0ZsVTR$yyhV*1IB((NCi4=r-rr)*i{vsk zuSwvVk^~ijNYo!T`M17((Lg9@Hv0l?eu)=oZtIM+UScLb3NGp9i;7Q~mvLmXG1TNY zTl_(PnDanO;<(lq4hDiP=bN=PW*``ehC3U18%flZ=GZm9wyVM#kTo7K#M^hR@WF3x90gP0Dk{HDh6)#IISoax4T1`D<6N8VmmF zz>R)$F)$m${&s&bD$E{%ADatIoG!(Q4698ymgQqIFp=+iG#;Oe{22joq$Z`66 z5}S~=AzimW9={7|E7B*C#-51Bk09+o5RcOzO*rwrc>H{%J@~Nq-y`jR9_=F?M0y|6 z`+gdazksyuRkVwA20orW0|Bz>kMa2BNZ%Ta$2%zfb3DEW>4A^p@u!jYBR!1N`*A#e z9BB;c4EYiIVm=C>ms{`|kS#N{>G`u5!KUE1@e#;R^)=3!1UnzU1Ar|g7!HED@jC<< z{T&55O#F!Egu<&SG#|7*WYq4~FMs3pm-#36iEayiHs~GV@S_~(yYPDtbZ&xx?n+?O zAAxujzZt;okZ|JncW=DTc~Sif__d+F4YmN?!Ur7>+4au~1mgP^eovE4k)po%8c>o9 zA5$5&G%3YFyo$jiAF#&>AZ2frZ4s}9sNaKn`r89kzX`kuemUT80Zw|OHdad6$&U#B zo`7@NwpwKGLjBY5BWhcZ@}lt2Wkq_aMvVo$=)XX z^M!9iAM{58Y6=In2WLL?iMri0_DsKf+C5W^-|C7ns!87Uz+e9F&?(Y1-uh19k__Db zsK2m3=}RORjg9qyJx&9)rm*9|!iNg#cIWTOyF2%u9OJP>Q-u38a1Z?_#!t?$cF^CB z6x_Ff8$E)tEBcVu-`}O+7GqqUcoXAE;HJs&UkP05>vG_hza5X04I!_^Hh-V6jftuz z8neI07#IEOcho%C`cRAUIsNrFxcvy{4&Yq=K|KB<@`_i7^aBEskKtR;Y!EnPVs#Ll zV#0C2A5cJ~3-Nmm@Qx4T@ofaR%2#){?H*&*z50FHhBsdS)vLlY#F!`s^B;o7+6IyT z_4um>{;Gk$YT&OLI6E3R>~iyldSpsd3>~c^VfixM<#6+y`kOp+y`nr-)~mmlHeHro zGNnHXLC2u{`)GXqfwHPs@qdf%29&Y){}K;T`l9ZpgvsS2+hh}E^|y-#by23Njt*MW z(LvKG9ejO+^c-GFo-kGM!# zWiDD+wYW;@mDY&DRzlw``3ql;c~K)7dQG^aOQrS622=dZHSN1%Hd5*7Yp9Y2#zdrCkO5 z{5Wh$)z{&tYp!!p)OBYEB{t{zz|dXJb1BgrlL0hVA+LRM@+Sygw|^Un@pYWE`7`EH z{wKiEK2?4L@-~|te?g8Jw^H?jN#`NaUG|$P(Off$*Go9*)5<&m8LPq9m{R7Zd@r4* zmT#bh)MiX84^wg!CtF470VMW(+pldoCy{fU4=%RXY=u8WfjMfa^tve79CXobdqb35 z%y}Myj_pmG@ggwMFT9pOB1NfGY&!zg=$if&km$uux-2wukhjm^J#$?I+G5AIT|QLg zyp9UTckPwPvz%5cd@r||xUt-&Nb+t6{6=K*7b8=^3S0y&BuLTkfSrp!$O9mq3-2W0 z3NX*ThXd(cNEd-cI|=g%4y1G8_XxO`fc+du=feNQ$u)~)bH3vu3+4O@O*-F`vh@Sv ze7~q42zt&(z;%95{um0joHi80s>{=mN#pbx4Fdf=C3y7`bCsgMYbyHaGxu`5~(YX*`R%1neROiw) zV1bLyh4&DU%$U261L<7&1OYb@@cSG{=R)dM5#GjTx#U9yE;<*!Lcse8Gsb~*F8m(? zeg~)A_c@Txh2-=F+>(X4P)334^VIQkc=mqEnml`evg9)bt{+jBT%dp}xv++3NjZh< zc($9e*YfPwDBHlZ&rr6VXAe_$3(x+RvO9V9&y@W#vc}!WIcIX`c72T2Y|dFOGF#4C zs;DUX7vzEVGL^QLK8k!vvGdpVKLcD!op8RE%k$)E&e!vDVSv(i3Hgn@X~?s@`*0#C z_sJrbM=Yp@mz^w+3`l0LL%x`52YXH**egA@XSSe@3A?S()joE&M#8 z{Vyt9D+_5{vK$*2xK_FDB*dI6Kg2@%{;Mfr^IF4#1q^9p`_TjmJ-uAgv9<4PFkl+OBYppfE>fo;BTSo zN!OyYz~qO+A8caUjjkdB*5G$3e$E&%+U7E5kQ%6lpIFX&*Sk@`!y$m@YU_=6we`8$ z)ktvnB#(#`A$uKIHdaJlpm8$C^@fo1#?NHz0Q zl>aCEZo$vS#Wt4_OuO2?nJ{MO{|8ER|LH0G?4Kpr91eR6<)ipHnh7>{GU4SIhdZdh zz}!jDc||`(z6>2J!jCy!KgQXWBTVXa{RX8RVY=KS$g>B4g})rfJNPCTO&d^}@GE6rH`T&4>-Ep$e6{`soa^;F04rBKNI-VZ5wt=-ZApO~=`Tb1 zF0BWBTn~hYp@rl~*Ge#_muRJ$Q8>MDUSSysnO349mq(D|$x!87mY4T8D8dUTF{AL3 zyk&Vy^VXC>YqAC_Gkckqmxmhr(mV|{jsk&*;+nE0xDs+oN)CWHWoVESfE5wsNCM88 z2y#EksEIsHTT?~|`4uQvqoM$jo3~zgF~=w>LsQFf@mHMSDTOGREM$^RlvOx*Mt>k#Z*Euk}9wXi9rOFe#Vhmp-{CmU8xop)Hf)zN?S3ND;hmH zcPi1ir`%gRm21|{43|*!nlgRzQ?;;=GZlY1M|9b_dUF2xRt?>_yLRd#XfgMTx8k#?IOkF-TSg2Y`?QlZU1aoLAO&9~hB>X`NW0L}MOOlH0R;@`SM+yu`PGwcs zCm}{o(&eNdSWS_TEQyuwn8Flxk)c~-edJ8(Qwlj^0V z|M0{SG*g&CGZ@l}Pr`J?c`#0?lPp_;YO<_QoUm-EupYeCVz_buS&2sWJSWA5pyW18 z_dlAv47LbooAyy*0n>00BK}uZRYz`)H2FIs)$%W-GyGL+{O#(h4O9zml-qHEWp`BB?T$J2IgZ(O`%Jsx zm|Zs6?g0F}>GpCHRYrc5y}(gs&!NI>d%lK5voEf)JF%M79o6;)l+Lm*=0(k(&r=}F zvf=pjJbNWIWZLH#O{U~JGo9;Vpx8~x_0mzeIxe&ubL^T!n31mE40gk)>XdGT@zFrm zQwpo(oR#DER+;X0+vKyap%qg?GH2WkFpvy&~%LWwbg2o6`L20EZR@hArU1py|DQE-| zovZ9xxoMh?IwM!(?tDEoFuuVQOb(_Vha2Qzut1xuMv~exG8ReL@G)7fqTH|n!^aC$ z-B`J}>VgZZTawwvNGHR7pjorQMAb!AixT0*6NrQ?g`h9o!P-K>7L%W77s%tG@N~gq zPn1Oh!HYc2ZK0b2!Db6pXHX(7x`>ckL*XbM?m$k4Fi)Uki=d4(hC2M7KogZb&A#?P z+s$lMTk}O1daezHn^>^5DJ&2>zynOFz0M?`V1&b>ixw|2JA;uxOVHnBkye3t;}H8I z4+YRg7fI=sKsZuD-J(TuU(~E@Zwo}DZT?DJkOX`|lo3=fZR@z`LbI~Pth{QmSqT@s z6pjj-%4VcXmcl*ZzJ3(j{oxjWB_6V>L_C01g3$<|;ZP@-1zW%ik2(PhNu@s=4u((& zhQQF*ctd4J7?Ha%8VUm#ZHrX4<5{b=OUd&CzP3vL7Jnnx5p{qCeeHf0@kxcD7m1EG zw)(ijJh%A6Ar|xyX5^Nn!k|AuoBWYRf^u~T{Yu?)gYq`OzR4H$N$VvVNHJqm8}rnL zLT#8%I4d%?GO<4tL`yW+C1G0@f0}n9VNBsgpe6`Wt3D-ZeB9xL^W; zOrEH(B}o?uN=Leq`;ZhXS??oZND<7l<|+@LcRigExDU(`4K!AU{cWK}1n&&vO-_Nr zbuJ#G>%e=Y1CbNaueqT!(8e7@Oj_BzVf~sqRNWYe1R4VH&YLf74Il^x*|6cx`B^7L z8Eq}mbvQ({%^E}P9c}(CW>cuMq0OHtdM;}V`Jxyxsvd)#TLgZ9K{s56(dTH2{RsUu zMJuK}w8)lWN?*9K6%inUIn=}FP*2zwZ1Ka&jctBkSinxH>C|Z&OEt?Z-6Wc7iv(^# z|7q$*v_Vu0Sm6!6h@a8;@JB@G2}C`j2ylAmLX8Vk5|Rco@u}eT!~I9_FJVn-c7F^4W#S|7hx^ssEbU&91+L^#@ra9u z(gS{F2SGD@Wv0z!u6ls_;LH49TAk zzfQuvY4}2)lUYZaKL;hgdOl0>zYQ6h?7JksCMyJ=;p1@^#~%)-8&)KzdJasok_m&;ui#%8g^$`tRQSq{>K3Si?*SjukAf>ZD*20BQ`@C`ej~}R_SzJG#bNDounyX>Gxnw37;bUO06f)lknJFH|I!rbkKW8r6QYhUY7+E#Un962ND2I5KI+GKtU1-MogstApIyEco<* z5$P>`Jr)9-?9wCkTrAu9oaFzwj7$9eBGi3J!XK@7bIdN;uZI9PIVAP;4dSm4pC5m~ z`K01f=_SHv$@PhfC%-0q_@TPfqTqNBJ)>PtaCkxD*@|tlsUJgL^3Qa?YL)nEeZEoR zyU-BXt3%EUk4tzd;G{P-uSqqqPXeBaf0g9(>LNGiz~4(k?ox@L?$2u^{@m*Y{)?Q7 zu`4-T7A%QZ;+sVRKZY_L9Y{&eU1|2cMdB}+>gIU-{VnAFS;CndM+Vso+0pSqpO_fA9DUu$dg+~oJ& z;Asvrz=BnPg`<&ZXLB<)2AlkN1DLtdip zf~&nfL@9QU}FG#@+h{2S{4huKoqYy^G;mhi`)<)Ahr$t!=b)NyQhOQkN9r% zdy>T#e-vBMf>gYUO-$PPTiljAohjRx$(>6m#B%e@f)7fyaer8%=}vdQTOU~YijE}i>nr0%sOyKBowwnM%)Q*h(yGeD>{SC zdk|YmEv;Q~jpqX9@$-8b7BJqdCb)^(IK_R(nThG?Idx zv@_qihG3AN%#55I5AquUSFME{Qo%`q>l3;c9!A<>%{Sp&04cq*0k#N74>gH zp5HR43WvB4SNU6I$fEmNiISiYVNOt}JQ(A?DsE)8gun}@D&Bx#2KQ%GxD7*Z-9uP^ zLuU)<=xz((qR4N8sH%pBF#KPZ=&q;ALoX_e`(`RDIa#KjQ_9j#63yXQw(&#lV=j?^ z^qnR(-%E72{=Ony$DFx{mbpGL`!pQ2a$qFW?jy~HLQI@J1E@uBCH z@QQCp(Z8s>0ipM?c*5Vkrd&F`s1=*%^gNWJAJpBvYES}NWrrPrQdYIEu5arA!xAb% zuipFGBn7++b=D(Ye``^Rz3GJfYTx!PNl%Yq)1l;7a;kI_>gb&y_a|e1zk5;52Zf^!}oJi=+*wXyHQ}|6LZU<#*G3! zf{e9&wU55ONnp%PBS>%m8$c_>Pl>7a0gkr|`gD9%R%sv5Xir$tt9^&TG1C7Cv}9^U zulDaxNcx!Uzw$5DuJVJQf|gJez1ru0H3T3Ig(pf$|5bcmMunAL-48e}>AMu6Ock9< zUrVD`*Qu=?f*@P_itSNkh?kOIU8ii3^j?K1Q`N2l{|*_Ff1v`%RMDqj%Sd%{8bTe! zPr)Q9Pj<=nccoPpTal2b8wY799K#F?#7lETs?O=Sc>tut2=^Z-u;BQuQj91L!=-)E zO!T$e1%a*tUl#g#l0IF3D{m77KU9vFMz7kW@204{L=nlIBB58dtVcTTvMlt6za*%3 zS&5NP*FW(~Yl2gFzbptlXmI10jh`Psi< OhQB)@a^jp$|Nj87K&ov3 literal 0 HcmV?d00001 diff --git a/CodeExamples/Loop.aarch64.c b/CodeExamples/Loop.aarch64.c new file mode 100644 index 0000000..38c7819 --- /dev/null +++ b/CodeExamples/Loop.aarch64.c @@ -0,0 +1,1125 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_GE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifii)(int, int); + +h2_insn_t * genMul(h2_insn_t * ptr) /* C compilette prototype */ +{ + /* Code Generation of 13 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t increment = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t res = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t k = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF1F03, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + res = aarch64_genMV_3(res, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + res = aarch64_genADD_3(res, res, increment); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, res, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res, resultOK; + pifii fPtr; + + if (argc < 3) + { + printf("Give 2 increment values\n"); + exit(-1); + } + in0 = atoi (argv[1]); + in1 = atoi (argv[2]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr = (pifii) genMul (ptr); // Generate instructions + res = fPtr(in0, in1); // Call generated code + printf("%d * %d = %d\n", in0, in1, res); + if (res == (in0 * in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Loop.power b/CodeExamples/Loop.power new file mode 100755 index 0000000000000000000000000000000000000000..c89a785b7e4a891262c6f35a8e6d18d2f8fe389e GIT binary patch literal 78264 zcmeHw4SZD9nfJLflVn0d7(T?{7dHYnq4@$WP87@}1W5of%ZJik+sP!EBvX@_I5W{` z6B$_DVyo|lU2L(hR@_>PUG;}8ZfT2c^rgP&+P-vaTWnF$(r%)xFKyK(6}|g^&d1En zWF`qnD!={Ri*uiIpYxpOJRj#g=iKMsTsN;+bG1#=m^y6i97b0jCvy?bLnjGpqYY7LV_8xP6AGk zGKa@o1y(`EwGn5MRsTTL>mO*GUcm+u2*(}?RXY-o+IeIq4k(?7fI8zX>ll`T$%TX!6 zg31qN?SaN6mzA|QFS)EV5-MFx{gN!imuOb5-H0>eexAZh;zZ`n!!H-VZ2YF;XFjMq z~HMRM05e@{SEv(fa z?ew+!BZ1retfMm=iu#+Pti#vd9%^EdXfqnJmRrJssGs?wp#bxGF_4+9I zK}Od!q?WLiYwD_(dl#23x*TM!9igBk^FlV;h=1m5RN~O^uMtp<^RI0GGF)q8?YtIa z$q@7Z5?re}OI3v?yc&mucQG4hbq>ljcGQt?!po_`t8^1y%~7f-G~vy0tlWgBF{lo= z2~YDt9Uc?jEPt&DPxDJ1^(MS|K5jDM)tsU>4JJIzRduwP@X2#m(U@UAs~Ylb**f@$ z{jOf!5nF4nqq5EAS;{t7yC1PRdt6K#ddMgk0=mH&vkfq|t1Op&SoO4FtOlQfd+e;1 z>YmypU;`^~qs_o0c4v>yM)M~A)c>Y2`ltHBaq4Twsn^G;FCVAAVVwH>aq8XU)VGaO z?;5ARevEqMzwVr(o@1E>-7vX(3w%gE!Au#_W46JQ9~u-U8}Q?YN6%%&C}lD+p;2s5 zKgCa7$F?-OV_Pn+VEIMx@z!ey?}}|5WURQDu4&xR*rKuXI{GDl7GRvwc+p3VkLrfh z{I|O6^}p|lUUWxKH1Cd{d$l{_edV8aU!>E>{-DQQSoKKmH6-^5<(s{x7jL!)tN-|J28hu#;liR=@D>?$55>7b?4 z;U=j=C)+&KJ@1P>-Jg7v>(On}qetp77k#(EZglwG2hy*l#j~unWtH#C^>w|Svuk@hKU~;b?^)G5g{``q& z)2{-3QEz>H5vNoA?nb}c|03)$3;mFd_5jx_am0u04Y-}kIWVuxc;Z8}&Ln)X#OIpuo^j?H>GCtF3(2yJ;xLz~x?(5#sJF%b zP~Vt)Vke*PtO0X+!gE*INb#ldtjG1%E9S#rZSXyCBjzHFN7cs0>IOB&h;~bPZMGbX zb$|;oc9pz!+b@A{X&ezRiamhasSS^nvOJe%7w#~&cxcS-qxmzGnAd$=Zx3{@yU#Fa z{?F_6oWgiWA0ve?Ne|d=OZi%oy{K2jp33bcFOAn!I&*rd^H8mrhwj?Zx|1F1)A+?a zRv)P@;dXhXy118YPuGQj7<*d)x3JnNSU0wMNT%nq7T!ws>t0>Q=L^{)Dc-Sk@lM&I z9P!T09>mW}x(`w;*?OYrR-Mt>#Ts^So7ZhG__Oc>tuN?%7{9?otd7=?LDCnp4V!sn zv0ZM81BGn!K!&L;#WJkBRpj5p@b9DV3BHEW;Qm0CsbAsiqPs9Q0#{`g;U>1I*o}5n zR~Wl^5Z73zE`hCfVcm?miQftEds*^$AN(FS@gv)x>YAYDh7KFyH}IKv6E--Nv1eW@ z)jG2WJomxw{p?3W2ia>whnO*Rn9UtN3Of!k@9_6wS7|HH3-Aq%ck;ap^RDWov6}pF z5aZ(4Cb~D1=;lbe0nqJdm3IX&xBAikIkeF+p7*jXRnMZVp}ZS-)#v>vE53awzW|zx zVnrKiPP}Rpko6S#X@0+ny24EYca=jx8jpLkKEdaHKOa9ugASI>V^;r`YQQNNKW}zp z9&g`+_WPJI(9h-$9)$dd*lX^$m(adtaLCEBhh400IA6xfDDFFy9{WssJZ92kmr0Ku zQV-H^TRJ_8g&uE1j>(pPuPq_J@`L9i`a%B~{BT@L=%M^TdVCZ==zm2&6hnTB7x`}> z{`?{J`a<=!sJ~0rtGPk*??c=x#NJp{f%|drsb01XWg3@zvo7g<4rBRQjOCwVJaw;M zfjJ;zQy+MJa68xN=sS(rc_!lAr?GBKB+f08bmlmB0)C=6 zhZs_POvVQn%7=khzI+j7f1-NRIyTDRGPb5# z|0d$^ayB{suFX2T^);tvB`<6ZSXxbd1-7WW{yRomE z^PgkyM~8ne>eU{`g}ut@?ngT$FSQ3s$7>?{(E`a!?V-}~Iw|+InVK^xY_5powyf z<6qlm!=50M?+LtvrD!jnYcA|PgnKo-gW_iF(IJ9P30)HAvq$@gMiVr=>|oFDB%G5C z^6Oldy`8QNgCRF2%Cjifg}t^K13KhL&Y}O}m{_N2{Z;-Yx+&Vooc!aG&Z$*yr~MM? zH~_leqfd(4N05VhgUgs*dU472WT(T(JsxFq2k|Uo@WdE7d5T*~-xH8o=}Y&fN?*#sD19mCru3zp8|h2WIVk6r zQeT;aSvZEiW98iHPvIWzRP9CC-`rF@W%7tK@RbqVI@#oAmxHObn&Q}(xqR8hcVnFY6Ur3dD2@>?Do0WN8p>C=MDFJJj$O%G%j^xJpSVF*yHgjS+Dd?=XcVV{QhOg@K2C|^htiE zQ6zbhtmFBeXq4Znto*L<H~CncTv9-Y?m=lEDYwdbPg*87j^`84fa zPUSs;bn?FmTcqBvOe_{6=1=%Nfiv-ZI-MSW4L_*o(>pPzvwuGJoF4oSQU85D4~vS^ z#q#|!mXGy(`ZJQ(>F!g^dyDCk7x`_x_&_vjU7)gB7Zm<%eLnp?tbG%CKD}Mind8Gz z86W7`>`U_bH0>J>0Jt+T$+ezG0y@2wlF}iL1=hKvLRcq2@y{D6(;`yZc zIXvk}_XJAMQ+^I_dgmo|Od0z*{1c~ePe5aEqVFf^rstE&zm%&yWB%QBcKFwAdLF6t zq;=wq=@~ma^sF~Mf1DIO?>Ia3OqFvr=bAt6`5K(0`I;){dN%1@I!St~+{HocFCKki z?ES@EvR=jNkFvk`;Ca!PTGP_;N|y&Q?=PN|yl73Nd-rs_(&a(S&l~-c7sdLsWv^m> zC!F3truUxHy-OQg>sh9=RX%#3mgwkRWe@I^C;BeCCz46W~X=S+x(N z+$`-)K2mO0zArUaE}HVTsoxLB-!<7M{w$4rG|`;2Ys%=H^jW3%DLhL%6}|KE9w^05 z8k@@B>RCDYn{4oL`r9)}{?_px=vl4zB>B4#_gTq$tNjc4TfHNoV#+B$d-;g-J2pvr zm*YN5=}r4`^~{OxKS*zNAFcGJ`)G>O6r1;;tkwg1Hc5G@QTNdke8zS<_tB>^pKEcS zrSw$u`K$>6E}~I6Vk)Z~vBFR0GvlMU{~EwE;}dvhJcMV)Of!a@+T3B> zI}GRJU6)+>9?LfPh~^f>ryi6U?l15R70F7uiZ58ZxC+A}JDPIMg8SRFNAo^HO5 zHI7RsX&kp<525rPz<8zkOM3`sxgF6@tN?%;>;fAaf26_S^-T{>Rm3)+{= zM*N+D_KB`<{0sJc)YJYe4crJ?C=* zFb{apaXv$U%05g>*oXF7#Gm#f#K(c$D(OWzP8|^AZTmDp&~ZMq0Er%XVBT)NgcwWw z`ZClLAMC9-AJlU`g@7*LLC5)&0}>y%Z0C`%R>FGJ6Q8A$59&Fe8o=qmgO2lA14w)} z$aXhK*eqc?>WR-L$p`hEPXi!*`vY`wyL6iD5|iz>$@Wp%zFW5Mk?ldp`@dV#?~w3* z2_Kg2`(%66^Zs|r_MnURzgzaN{IoAFk9bDWXY*nX()*v{J1%mr-8biZw5R+W#ye}+ zDZVQMntr_3P49Nc+!#;G<_^vCt@t-%_0;dux9Tu1rF@4ZJS^c+$V2`|J-6G7Qf|<3 zxnBZ2#x}b_C%?NT_Ra^jxr3k?JdFL|G3=d>WAFS9_Rc49@4z0(e$K$(7pAfY+6*7Zw|6LJ5kIoWomlT^ z99|&xpD$stgqJ}N8i%Oo_Ryt0K*#M-DC^4s$!{0H5A)#%v>&`o`XQA*KMJzpw)Qu+5OtdnM+^uzbGc9M>6sgp;-S_$i=4yflkE|ofhj_X(h zNInPs_B~_xd=2W!=Wh7i1E1Hz=k?O(8}Yu_oFv)yLADIw4q_gU<==yt$A>VF4`Uu5 z#olH37sl$Je4A`i$-fcy)Ema?r*WOoyN-{`gE9tTULjXrS7EB>Ys3br{|yp0OV|!Q z$mgi%_Shut0XlAv20$LO0mqsHZKx+1H^3e@z#h%8N4w3trF;EK{yndXpBtc%zA%^pCK3-n|9=?>JBT%C}s8*;@U*EZ>=#}5fR zO52&{cinIWd^Iw@7vXPs>iBn{67fC}Tj~2?eYVX50krGGe4x31$ad=Qc>CnL{q!A9 zdLM5aay9e~%$S_RfLrKq=5^c)(06?{VbA>Jqhjw#-yOU2TcW%T@q)hBhx>Rg%j1%U zcs5{PLiH|F{XM4oX4ErBgZmli(uRByegoQjB8Sq6c+!G+)QDJw@?iIJ2mi)p_v+#i z-vy<9y20l*(6)fKk<(^^b_M?~Cdu9j*`L}i*aT1(f?cM|1I?mRCMklN1Gc^#;+RhJdFD8u&kqc7XRL? zVQgKd-+uR?(&J~4xe$67Mlrn;Q1uAD2Pu(!+UovvB@A=Z;))TCo_&eE+ zgF3#M`y#%5dJw+@`1RwrAHRM0?Zs~oevjd|8^4F~+l629H(4KoPIE9e(R~BfkN9`* z%r+|gjQpPcX9e_l1=N`MdiH`vO(Z^BP`@WJW@%^b~i0T?O*k*Ghc z^Dm40qJdCQZ}A1%{gN)w(%uzmyF!nDf?T#M6ct7K)tp#w3N`!nR)5eR<~-t`#=hPc z4hDj)#rpDV>h(Y{5)F4X@lF!7Bl^3}*M4o7q%G5Z__}!;;4N$XL4cbD2>V;thC_7i zYwz;cb#w@U)~#5{3)fZQ3zazP7c^f1jms7^l`Uu%|8be(@~mGo5ph_8e%&e3Z>*k3 zgE;@{s)>*%OV{I9ugBIF7F6H_-qUsY2xkq+YWTt5+N{QnOEH~aO)plu5K zJN&_@aC-#fSYN2)vWLI1mr(iFpF>2%w9m(G!MI4!8lZ9&qV*3?mAd|3kyr2{`M=hOr;; z#peyb$-miqzmuq^{!m}e>sN_BsGj^)44=G1^;hS4lo%n9Q2h|$ z;iHEM)<`|PiT3%B?GDs8P<^%Rzdlj#M*RWQ&lft>EB>FC{5JuA5We3)?M?l!M7<6a za&+t@>IdM95jL zF!qVQ_QdUN*W)x!jIm?S8O9K3!KXh?W9y`@n2ujDX!ac(n}){n-7ko-HbNfTU*ddd zoNxQ7VLXOS$OszygU|GPjfMo&80+t0V3s@Gg zEMQr{vVdg)%L0}KEDKl`uq zU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{ zvVdg)%L0}KEDKl`uquFSzqoD^_lYesH~qNum3^9 z90~I!JV!zW?5e(rUy8FDi6aR_y@6?%x_&8dUx{fb>eW0Z zIp|RHSj`)OO`L_izC`=a3V9DDNJf-Ie}BO=7ya#*al<94Hp%g)u17S+#X|g~efSje zNc-F&A<-|uZv%c>>?hFM!AN$e76E9m?7z=UzzUwu~nL>|e)8E4*Mnl|KZHRy6BIlpT(YKrqVew^Q}P*`EZkIWx-8 zKEsKg))P1UW47~Vda3DWP-D-Z>7nvB=rm{6dIB*zoi{5?-~>*Nf*Ici$jo*8+L3Lb zl;r~}#}P-~4{^b=ZlSAJ#FZoKb-H?0TsfJu0UbJCbJ$-1B{XxR&+IRtJP(B_i&3zX zkPC5Tb2`o?;Bw3W$oV{bY*_q*$twpGjNf)H=_n+HuV8e zWj-~fmzc1;dH~+jJt**=rm|^H!nz1E{Q@-2+lkUNC!JmYLdYl~ALmFqyS_`vec+q- zEJxDW^&%l(BIK_)lFqKzamw95vSt0zS&GW3zk^I!??~C+1t#m=X}4GdxbN(}teSuDPP4LWO#KxfsrdfAUcNtn9 zxyq5n$uqTcs)%jYkEt$8)aA20GUqfWon1R|noi3>-q$&j&aTG^xsQ;f`ZOnZ0$zN8 zip9M6Z7N>Qi~pC3)x3Cwir4TW8QHao7fD-J6EE(jVvrY~rsA!<_#affgBSmkivP%q zC#m>VUYw4z>l--PUjQ=eB0l1CThN;$Yp#>rHZ?{S1=IGR3^FG`*5_wDg7QpP)~_?B z!_c!T33+4+FJFtcS+C?25WbM`ujVX5nPq2Q?sM@ z+yPk~ON#7&0*Q=p_9LLN{p{Qo;NZ9nCmBUEMAs_Bh}e?Z4g&gRF{d*O$m7J6H7HG? z*u+n$x(8*a^Ph2+;WOuXQm6N&_&M2Z?^wv&)q_mAB zjYONVQ!K$R2n1%bM06!E=o(cBJCRV+jlSmQuq4ElKZ-I!LVy}$hWi==CBabCU)n@A zh_+KF*j=-E_}Lk)QKK|Q+dx#%vnVH{6=M{cNq41-gk<`ra5Rvxyt-|${~tu z;zp`05NvAiYW6b*>%qE8MOe4lPv)dSl0ovQ<-mS`X&H9=w9*VM(|(hdQD~phlA+my zI+cL52bWSw7dRr!Tr@Mosb$PYvrJ9Tz@qQ4XD-Wda;RnK97Zx`69kPw)0x+R(X6F< z=6CEKs&T~|;NEm}fEZJ}^fM-vmH&Ti2*(iH0Sdjrj&kG6&VzGiRO-x`QS{b8#2w)i>% z?YFWO?JY|#^IjhcH?v?{Gp}0W?F3geBMG`#dnnkdH;1|!+x>}Nf)Rn|mDE2k@KaYX z5@-$jo4Hs}Xo;65=b|N2Znw~lBU#Yb;pgUAzG#uW*VjurFkP1g{C+>N6CDE?4AD3) z@kOKIKx0?b4;0mx2!fJDi`{xjt6p;LV!Z^Tc^PQIvZMvjU4fB~nSdrO9sY2uzr@$x zUeXi_!kxir1lVw>D~Nd0imsz=LB z%V-h>eC;LvZhsSt_@rH-WZVu-Z9ZZ0+x+1W3wlZE$ZZK*!py)n`y)++6^0Ss7cSyu zvLUf=_CmdCW;FgDwr!`GYrin&Y3>OEcGtnd)sp zo3nj9*4HgR#Zl=Cw_<2QdH5u*Dp`l2=4K#GmhuOi$2Bj-Rr7JJywKQsRop944)!N) z{ex!W(Ph;}V;fX)N1S83Dw;WNm@vnUieq1#nc z&wOpimcXs3I8f&;C{ybwOK7$=i$v=~+=N%*IvskL<0Cwa` z)$@aq^w~^3hZu>U!c5OI;#GE*!y2UB;z$&b=3qxt;-|**za#1MSSowl*)$ewl9>uq z13OSRG^fH(XZi=4x?hjCu(KJgJSBc6^Q6SjV$4Xzhn^0Ne%^uf3LfgD!k^1xDe-il zIQpP2ed1Ud8dF{Yyz0TSG4EGv)DtVrwP-L=xU7@eSD{$JH&s zYb@bM(w~mM$B*#aq<_WJ2gWGxM*Wsg8ObM|USH*WrnADNarjM+cd>!ik$j$#{2OF) z3YYx&cbrq%^Dyuv=ME_+?)3OEDDgX!ON( z6L_@@d=hx-w?B#hrzHMh5}uO&)bGh@f=`3wPbq%t_Xd~1&&M?#e=G4ZBu?mBtuxKQ zr?Lalq{4?dztQn(hs5`13I5ccjvq=qLg(}lXy6GbG#^<&->Eg zAIAjIQ^fNZB>y!f!tX=e-;5mwe!7{lEWZi73w&a7oGX$)NIv^#3qD8W3khE#eBN6I7hS}E}_t{3)oKGIxCii`~PdzfVd&D%Dsc`M4yXW*JxCk@)j~Cw==QAL%YuD(P?dl<4;{ zY0oPqzU?Z3&zCRMtOB0oNgkiqN&3Ri2>MO3gTLc=DTE1hNcx=xg8n4s3UPcMc#?Bh zl3(tW^e@S{O;01}*g^F0OR_w>IK7}TpTC_3|Kl|HljvtgV-8dI3yRmvoIaO1rF|My zg((kex;r0vZ;jjMNVKb^1-IE=@A3`TuJf*`Tff2U#Z`^zs@boyN#1COw+X2je*`4W zA#ZDYsL|K%ZAPL5$&9XU))eaKZ1+d~%}9O`7CEVIywlMVMjpi5+||)>tLkaR+8W-` z)$6LRS>aVz37(XE5j@v~LY<{N(+WA;7UK>!5?tvI`oli-Lx?6MXMorcK!ORE?V;Ai zf-VqUC(~fp_#!t(2pRTA{G+kHNQbwRGmrRg_IneTt^O#I5u$0JrM)ZCMoc=8R0=hj z^9tqsSX5Ek*&g*ap}Mp)j8sjF$Fp)xUG;MB;?hNzv(ZFg-|1`h)BXB5l>Y8ObR3cn znY0>*Oy&i6ngp5zf+Og?@M$1;qqly|2AC?;ezQM?*qvQbN^~VPOv)^b))vhoBif86 zX}KjFh>m9qVg7MAbt0!1N)oZ=(`&1)sau{xBVRNW7{PEvqC}*Wyj~=Cy(?ZLvv|Yml`GJJ#J8?TsPHrJ zyQT|SMv+T0jTtj1CE)sv)#zHr4l$$S%&$j{d9<6_Ba$G|Df4!GingxzN9!nOg{nx% z+vW>4BO#rXC*-4P1e>^#dA=*&^)=Udc|1V(WO4K$0|rHqKqz?a>Vyr}LCko=s+trbJC zr9a+Y<>3JNLHPqZh=vYzf3Nr~0`5J$YpeS2mw7orey9vga(hwB_`~TOT&VU(WqUw= z(0wl*w4I`&>R)A!mIH?^ZoIw9{{iyj9|VY>lkK+}HT3SV>R;sv0r`E@8!gNVl zyJY))9ylVA+tqj;vq2)_c@NOgq4RU%v;{?T`=c`73CNEdKAoVYl0Nd1(aS&P_9|}; z$d6(H;%8}=_%*%FMD3OR+T?u;AV273JoBOSSGapoFt=BERzQ9nQG^mE_y2X^&Fxh_ z7LXr(N&P3ce_Xa#WGZi~e<0ec`#5ox@SnP-`z`8UwO9Gw@(H&80oszQRC|>N_Q>}A z#2kkjAIg48t^=qu_aDy}%gm@6znlr3BtOOHW}v97`iCbu>vGw?liHXL)lR|ZQD^R7 z-4}Ptj+C5=g=(j+{~rqG{$sNLm~3CK2qjEz{}S-je|Zv}YCj_hFV&aa8GA*xPa&zX#)7Dt={`#m+WB%5T~OdyhRM0#(Iz_unF z%Q+;|(p%AlOSa$1JVB}A7;lV|YOmmhD5$ccAvk}Qz^+KDOuA%+KqTX+eJ3S!am4sJ zaZ0v7Q6-s(6Q7Xn2WWA_QGj1Pero)v_)Y1gBohIHd|H9%e?SF(jvXy4?GIA5@Bf5o MPp`C^kEBcX-?(GKmjD0& literal 0 HcmV?d00001 diff --git a/CodeExamples/Loop.power.c b/CodeExamples/Loop.power.c new file mode 100644 index 0000000..1b9a4c8 --- /dev/null +++ b/CodeExamples/Loop.power.c @@ -0,0 +1,944 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genBGE_1(h2_sValue_t P0); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BGE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifii)(int, int); + +h2_insn_t * genMul(h2_insn_t * ptr) /* C compilette prototype */ +{ + /* Code Generation of 13 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t increment = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t res = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t k = {H2REGISTER, 'i', 1, 32, 17, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3F81F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + res = power_genMV_2(res, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + res = power_genADD_3(res, res, increment); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, res); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res, resultOK; + pifii fPtr; + + if (argc < 3) + { + printf("Give 2 increment values\n"); + exit(-1); + } + in0 = atoi (argv[1]); + in1 = atoi (argv[2]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr = (pifii) genMul (ptr); // Generate instructions + res = fPtr(in0, in1); // Call generated code + printf("%d * %d = %d\n", in0, in1, res); + if (res == (in0 * in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Loop.riscv b/CodeExamples/Loop.riscv new file mode 100755 index 0000000000000000000000000000000000000000..796e54d3af574ca78bc1f529ba4699421095904a GIT binary patch literal 33276 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
BRlul8xATv#1Ru+on1qiOf ssrsL?|M`HWsF)Y1yg-zHPfZ*gnl3A?FEW+Ch!lfkl?Zs8E-6X&Uu4~~IRF3v literal 0 HcmV?d00001 diff --git a/CodeExamples/Multiple-flt.power.c b/CodeExamples/Multiple-flt.power.c new file mode 100644 index 0000000..2b58444 --- /dev/null +++ b/CodeExamples/Multiple-flt.power.c @@ -0,0 +1,1157 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_FMR_RR_F_32_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); +#define P1_FMR_RR_F_64_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define PPC_FADDS_RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); +#define PPC_FADDS__RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDFP_RRR_F_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xa & 0x7ff) >> 0)); } while(0); +#define P1_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); +#define P1_FADD__RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); +#define PPC_FDIVS_RRR_F_32_1(r0,r1,r2) do /* div */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x24 & 0x7ff) >> 0)); } while(0); +#define P1_FDIV_RRR_F_64_1(r0,r1,r2) do /* div */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x24 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define PPC_FSUBS_RRR_F_32_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x28 & 0x7ff) >> 0)); } while(0); +#define PPC_FSUBS__RRR_F_32_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x29 & 0x7ff) >> 0)); } while(0); +#define P1_FSUB_RRR_F_64_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x28 & 0x7ff) >> 0)); } while(0); +#define P1_FSUB__RRR_F_64_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x29 & 0x7ff) >> 0)); } while(0); +#define PPC_FMULS_RRR_F_32_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x32 & 0x3f) >> 0)); } while(0); +#define PPC_FMULS__RRR_F_32_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x33 & 0x3f) >> 0)); } while(0); +#define P1_FMUL_RRR_F_64_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x32 & 0x3f) >> 0)); } while(0); +#define P1_FMUL__RRR_F_64_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x33 & 0x3f) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FMULS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FMULS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FMUL_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FMUL__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FSUBS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FSUBS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FSUB_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FSUB__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FADDS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FADDS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDFP_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FADD__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_FMR_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_FMR_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (power)\\n"); + #endif + P2 = power_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_FDIVS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_FDIV_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 2 floats and return float */ +typedef float (*pifff)(float, float); + +/* C compilette prototype */ +h2_insn_t * genAddf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genMulf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genMUL_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genSubf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genSUB_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genDivf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3807, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genDIV_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + float fin0, fin1, fres; + pifff fPtrf; + int resultOK; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + resultOK = 0; + fin0 = atof (argv[1]); // Get the users values in1 & in2 (flt) + fin1 = atof (argv[2]); + + ptr = h2_malloc (1024); + fPtrf = (pifff) genAddf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple addition of 2 floating point values:\n"); + printf("%f + %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 + fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genSubf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple subraction of 2 floating point values:\n"); + printf("%f - %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 - fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genMulf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple multiplication of 2 floating point values:\n"); + printf("%f * %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 * fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genDivf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple division of 2 floating point values:\n"); + printf("%f / %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 / fin1)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Multiple-flt.riscv b/CodeExamples/Multiple-flt.riscv new file mode 100755 index 0000000000000000000000000000000000000000..486b1b0c0bf1e0d02a177de8d4b3b6ec112d2cd4 GIT binary patch literal 57932 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 HdGP)p5+gFr literal 0 HcmV?d00001 diff --git a/CodeExamples/Multiple-flt.riscv.c b/CodeExamples/Multiple-flt.riscv.c new file mode 100644 index 0000000..1355b01 --- /dev/null +++ b/CodeExamples/Multiple-flt.riscv.c @@ -0,0 +1,1087 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32F_FADD_S_RRR_F_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32D_FADD_D_RRR_F_64_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32F_FDIV_S_RRR_F_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0xc & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32D_FDIV_D_RRR_F_64_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0xd & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32F_FMUL_S_RRR_F_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x8 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32F_FSUB_S_RRR_F_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x4 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32F_FMV_S_RR_F_32_1(r3,r1) do /* MV */ { riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +#define RV32D_FMV_D_RR_F_64_1(r3,r1) do /* MV */ { riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FMUL_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FADD_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32D_FADD_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FSUB_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FDIV_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32D_FDIV_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 2 floats and return float */ +typedef float (*pifff)(float, float); + +/* C compilette prototype */ +h2_insn_t * genAddf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x31F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genMulf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x31F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genMUL_4(r, a, b, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genSubf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x31F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genSUB_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genDivf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x31F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genDIV_4(r, a, b, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + float fin0, fin1, fres; + pifff fPtrf; + int resultOK; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + resultOK = 0; + fin0 = atof (argv[1]); // Get the users values in1 & in2 (flt) + fin1 = atof (argv[2]); + + ptr = h2_malloc (1024); + fPtrf = (pifff) genAddf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple addition of 2 floating point values:\n"); + printf("%f + %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 + fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genSubf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple subraction of 2 floating point values:\n"); + printf("%f - %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 - fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genMulf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple multiplication of 2 floating point values:\n"); + printf("%f * %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 * fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genDivf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple division of 2 floating point values:\n"); + printf("%f / %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 / fin1)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Multiple-int.aarch64 b/CodeExamples/Multiple-int.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..fadeda4cf1d0df9f07312f9e214fc7c8e94a9cab GIT binary patch literal 52288 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +// X * NPowerOf2 = X >> N (immediate shift left) +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSR_3(P0, P1, P2); + } +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (aarch64)\\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 2 ints and return int */ +typedef int (*pifii)(int, int); + +/* C compilette prototype */ +h2_insn_t * genAddf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genMulf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genMUL_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genSubf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genSUB_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genDivf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genDIV_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res, resultOK; + pifii fPtrf; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + resultOK = 0; + in0 = atoi (argv[1]); // Get the users values in1 & in2 (int) + in1 = atoi (argv[2]); + + ptr = h2_malloc (1024); + fPtrf = (pifii) genAddf (ptr); + res = fPtrf(in0, in1); + printf ("Simple addition of 2 int values:\n"); + printf("%d + %d = %d\n", in0, in1, res); + if (res != (in0 + in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genSubf (ptr); + res = fPtrf(in0, in1); + printf ("Simple subraction of 2 int values:\n"); + printf("%d - %d = %d\n", in0, in1, res); + if (res != (in0 - in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genMulf (ptr); + res = fPtrf(in0, in1); + printf ("Simple multiplication of 2 int values:\n"); + printf("%d * %d = %d\n", in0, in1, res); + if (res != (in0 * in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genDivf (ptr); + res = fPtrf(in0, in1); + printf ("Simple division of 2 int values:\n"); + printf("%d / %d = %d\n", in0, in1, res); + if (res != (in0 / in1)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Multiple-int.power b/CodeExamples/Multiple-int.power new file mode 100755 index 0000000000000000000000000000000000000000..80db09406210c6b8d25f2ba9ce64b0566da20610 GIT binary patch literal 78336 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 DEbbwn literal 0 HcmV?d00001 diff --git a/CodeExamples/Multiple-int.power.c b/CodeExamples/Multiple-int.power.c new file mode 100644 index 0000000..237c287 --- /dev/null +++ b/CodeExamples/Multiple-int.power.c @@ -0,0 +1,1086 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (power)\\n"); + #endif + P2 = power_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 2 ints and return int */ +typedef int (*pifii)(int, int); + +/* C compilette prototype */ +h2_insn_t * genAddf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x781F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genMulf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x781F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genMUL_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genSubf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x781F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genSUB_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genDivf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x781F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genDIV_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res, resultOK; + pifii fPtrf; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + resultOK = 0; + in0 = atoi (argv[1]); // Get the users values in1 & in2 (int) + in1 = atoi (argv[2]); + + ptr = h2_malloc (1024); + fPtrf = (pifii) genAddf (ptr); + res = fPtrf(in0, in1); + printf ("Simple addition of 2 int values:\n"); + printf("%d + %d = %d\n", in0, in1, res); + if (res != (in0 + in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genSubf (ptr); + res = fPtrf(in0, in1); + printf ("Simple subraction of 2 int values:\n"); + printf("%d - %d = %d\n", in0, in1, res); + if (res != (in0 - in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genMulf (ptr); + res = fPtrf(in0, in1); + printf ("Simple multiplication of 2 int values:\n"); + printf("%d * %d = %d\n", in0, in1, res); + if (res != (in0 * in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genDivf (ptr); + res = fPtrf(in0, in1); + printf ("Simple division of 2 int values:\n"); + printf("%d / %d = %d\n", in0, in1, res); + if (res != (in0 / in1)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Multiple-int.riscv b/CodeExamples/Multiple-int.riscv new file mode 100755 index 0000000000000000000000000000000000000000..34231f833910a10176eb3ed81122016c3ec4cb4e GIT binary patch literal 53836 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Multiple-int.riscv.c b/CodeExamples/Multiple-int.riscv.c new file mode 100644 index 0000000..7bdfe2c --- /dev/null +++ b/CodeExamples/Multiple-int.riscv.c @@ -0,0 +1,1044 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 2 ints and return int */ +typedef int (*pifii)(int, int); + +/* C compilette prototype */ +h2_insn_t * genAddf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF3F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genMulf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF3F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genMUL_4(r, a, b, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genSubf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF3F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genSUB_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genDivf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF3F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genDIV_4(r, a, b, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res, resultOK; + pifii fPtrf; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + resultOK = 0; + in0 = atoi (argv[1]); // Get the users values in1 & in2 (int) + in1 = atoi (argv[2]); + + ptr = h2_malloc (1024); + fPtrf = (pifii) genAddf (ptr); + res = fPtrf(in0, in1); + printf ("Simple addition of 2 int values:\n"); + printf("%d + %d = %d\n", in0, in1, res); + if (res != (in0 + in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genSubf (ptr); + res = fPtrf(in0, in1); + printf ("Simple subraction of 2 int values:\n"); + printf("%d - %d = %d\n", in0, in1, res); + if (res != (in0 - in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genMulf (ptr); + res = fPtrf(in0, in1); + printf ("Simple multiplication of 2 int values:\n"); + printf("%d * %d = %d\n", in0, in1, res); + if (res != (in0 * in1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifii) genDivf (ptr); + res = fPtrf(in0, in1); + printf ("Simple division of 2 int values:\n"); + printf("%d / %d = %d\n", in0, in1, res); + if (res != (in0 / in1)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/RegressionSingleOp.py b/CodeExamples/RegressionSingleOp.py index d9d5ed0..fb02bd2 100755 --- a/CodeExamples/RegressionSingleOp.py +++ b/CodeExamples/RegressionSingleOp.py @@ -117,6 +117,7 @@ def genAndRunValue(singleArith, opList, wordLenList, vectorLen, archName, keep): parser.add_argument('-z', '--analyse', action='store_true', help='Analyse result') parser.add_argument('-d', '--dotests', action='store_true', help='Generate results') a = parser.parse_args() + print(a.wLen); # print (a) results = {} csvFileName = "regression-single-op-%s.csv"%a.arch[0] @@ -124,29 +125,20 @@ def genAndRunValue(singleArith, opList, wordLenList, vectorLen, archName, keep): if len(a.arch) != 1: exitError("Could only analyse 1 architecture") else: - # Read reference list - csvRef = csv.reader (open ("RegressionSingleOpReference.csv", "r"), delimiter=";") - # Restrict the list to 1 arch - refList = [(ref[0], ref[1], int(ref[2]), int(ref[3]), ref[4]) for ref in csvRef if ref[5] == a.arch[0]] - refList.sort() - # print (refList) - - # Read the generated results + csvArch = csv.reader (open (csvFileName, "r"), delimiter=";") - archList = [(ref[0], ref[1], int(ref[2]), int(ref[3]), ref[4]) for ref in csvArch] + archList = [(ref[0], ref[1], int(ref[2]), int(ref[3]), ref[4],ref[5],ref[6]) for ref in csvArch] archList.sort() # print (archList) - moreInArch = [x for x in refList + archList if x not in refList] - moreInRef = [x for x in refList + archList if x not in archList] - print ("moreInRef : "+str(moreInRef)) - print ("moreInArch : "+str(moreInArch)) - if archList == refList: - print ("same list") - sys.exit(0) - else: - print ("different list") - sys.exit(-1) + checkIf = False + for test in archList: + print(test) + if(test[6] == "Fail"): + checkIf = True + if(checkIf): + exit(-1) + elif a.dotests: if "value" in a.param: for archName in a.arch: diff --git a/CodeExamples/Tests/Test-Address-mul-int-008-128-aarch64+riscv+power.hl b/CodeExamples/Tests/Test-Address-mul-int-008-128-aarch64+riscv+power.hl new file mode 100644 index 0000000..2b9dab7 --- /dev/null +++ b/CodeExamples/Tests/Test-Address-mul-int-008-128-aarch64+riscv+power.hl @@ -0,0 +1,46 @@ +// -*- c -*- +#include +#include +/* C compilette prototype vector version*/ +typedef int8_t v8_128_int_t __attribute__ ((vector_size (128*sizeof (int8_t)))); +typedef void (*functionPointer)(v8_128_int_t*, v8_128_int_t*, v8_128_int_t*); +functionPointer genSingleOp(functionPointer ptr) /* C compilette prototype */ +{ + +#[ +int 32 1 compilette(int[] 8 128 a, int[] 8 128 b, int[] 8 128 r) +{ + r[0] = a[0] * b[0]; + return 1; +} +]# + return ptr; +} +int main(int argc, char * argv[]) +{ + functionPointer fPtr; + int i, returnValue; + if (argc < 256) + { + printf("Give 256 values\n"); + exit(-1); + } + v8_128_int_t in0, in1, res; + for (int i = 0; i < 128; i++) + { + in0[i] = atoi (argv[1+i]); + in1[i] = atoi (argv[1+128+i]); + } + fPtr = h2_malloc (1024); + fPtr = (functionPointer) genSingleOp(fPtr); + fPtr(&in0, &in1, &res); + printf ("Simple operation on 2 variables (wordLen: 8, vectorLen 128):\n"); + returnValue = 0; + for (i= 0; i < 128; i++) + { +printf("%d * %d = %d\n", in0[i], in1[i], res[i]); +if (res[i] != (in0[i] * in1[i])) + returnValue = -1; + } + return returnValue; +} \ No newline at end of file diff --git a/CodeExamples/Tests/Test-Value-sub-flt-064-001-+.hl b/CodeExamples/Tests/Test-Value-sub-flt-064-001-+.hl new file mode 100644 index 0000000..4eed885 --- /dev/null +++ b/CodeExamples/Tests/Test-Value-sub-flt-064-001-+.hl @@ -0,0 +1,46 @@ +// -*- c -*- +#include +#include +/* C compilette prototype scalar version*/ +typedef double (*functionPointer)(double, double); +functionPointer genSingleOp(h2_insn_t * ptr) /* C compilette prototype */ +{ + +#[ +flt 64 1 compilette(flt 64 1 a, flt 64 1 b) +{ + flt 64 1 r; + r = a - b; + return r; +} +]# + return (functionPointer) ptr; +} +int main(int argc, char * argv[]) +{ + functionPointer fPtr; + int i, returnValue; + if (argc < 2) + { + printf("Give 2 values\n"); + exit(-1); + } + double in0, in1, res; + for (int i = 0; i < 1; i++) + { + in0 = atof (argv[1]); + in1 = atof (argv[1]); + } + fPtr = h2_malloc (1024); + fPtr = (functionPointer) genSingleOp(fPtr); + res = fPtr(in0, in1); + printf ("Simple operation on 2 variables (wordLen: 64, vectorLen 1):\n"); + returnValue = 0; + for (i= 0; i < 1; i++) + { + printf("%f - %f = %f\n", in0, in1, res); + if (res != (in0 - in1)) + returnValue = -1; + } + return returnValue; +} \ No newline at end of file diff --git a/CodeExamples/__pycache__/CCode.cpython-312.pyc b/CodeExamples/__pycache__/CCode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4ada0eb4cac08daf96790a05e53526fcb720192 GIT binary patch literal 10296 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 avwM;6p-uAqft0iH0l)Kc3&U4Z>HH@P-{=nj literal 0 HcmV?d00001 diff --git a/CodeExamples/regression-single-op-aarch64.csv b/CodeExamples/regression-single-op-aarch64.csv new file mode 100644 index 0000000..210b1d7 --- /dev/null +++ b/CodeExamples/regression-single-op-aarch64.csv @@ -0,0 +1,2304 @@ +add;int;8;1;value;aarch64;Success; +add;int;8;2;value;aarch64;Fail +add;int;8;4;value;aarch64;Fail +add;int;8;8;value;aarch64;Fail +add;int;8;16;value;aarch64;Fail +add;int;8;32;value;aarch64;Fail +add;int;8;64;value;aarch64;Fail +add;int;8;128;value;aarch64;Fail +add;int;16;1;value;aarch64;Success; +add;int;16;2;value;aarch64;Fail +add;int;16;4;value;aarch64;Success; +add;int;16;8;value;aarch64;Fail +add;int;16;16;value;aarch64;Fail +add;int;16;32;value;aarch64;Fail +add;int;16;64;value;aarch64;Fail +add;int;16;128;value;aarch64;Fail +add;int;32;1;value;aarch64;Success; +add;int;32;2;value;aarch64;Fail +add;int;32;4;value;aarch64;Success; +add;int;32;8;value;aarch64;Fail +add;int;32;16;value;aarch64;Fail +add;int;32;32;value;aarch64;Fail +add;int;32;64;value;aarch64;Fail +add;int;32;128;value;aarch64;Fail +add;int;64;1;value;aarch64;Success; +add;int;64;2;value;aarch64;Fail +add;int;64;4;value;aarch64;Fail +add;int;64;8;value;aarch64;Fail +add;int;64;16;value;aarch64;Fail +add;int;64;32;value;aarch64;Fail +add;int;64;64;value;aarch64;Fail +add;int;64;128;value;aarch64;Fail +mul;int;8;1;value;aarch64;Success; +mul;int;8;2;value;aarch64;Fail +mul;int;8;4;value;aarch64;Fail +mul;int;8;8;value;aarch64;Fail +mul;int;8;16;value;aarch64;Fail +mul;int;8;32;value;aarch64;Fail +mul;int;8;64;value;aarch64;Fail +mul;int;8;128;value;aarch64;Fail +mul;int;16;1;value;aarch64;Success; +mul;int;16;2;value;aarch64;Fail +mul;int;16;4;value;aarch64;Success; +mul;int;16;8;value;aarch64;Fail +mul;int;16;16;value;aarch64;Fail +mul;int;16;32;value;aarch64;Fail +mul;int;16;64;value;aarch64;Fail +mul;int;16;128;value;aarch64;Fail +mul;int;32;1;value;aarch64;Success; +mul;int;32;2;value;aarch64;Fail +mul;int;32;4;value;aarch64;Success; +mul;int;32;8;value;aarch64;Fail +mul;int;32;16;value;aarch64;Fail +mul;int;32;32;value;aarch64;Fail +mul;int;32;64;value;aarch64;Fail +mul;int;32;128;value;aarch64;Fail +mul;int;64;1;value;aarch64;Success; +mul;int;64;2;value;aarch64;Fail +mul;int;64;4;value;aarch64;Fail +mul;int;64;8;value;aarch64;Fail +mul;int;64;16;value;aarch64;Fail +mul;int;64;32;value;aarch64;Fail +mul;int;64;64;value;aarch64;Fail +mul;int;64;128;value;aarch64;Fail +sub;int;8;1;value;aarch64;Success; +sub;int;8;2;value;aarch64;Fail +sub;int;8;4;value;aarch64;Fail +sub;int;8;8;value;aarch64;Fail +sub;int;8;16;value;aarch64;Fail +sub;int;8;32;value;aarch64;Fail +sub;int;8;64;value;aarch64;Fail +sub;int;8;128;value;aarch64;Fail +sub;int;16;1;value;aarch64;Success; +sub;int;16;2;value;aarch64;Fail +sub;int;16;4;value;aarch64;Success; +sub;int;16;8;value;aarch64;Fail +sub;int;16;16;value;aarch64;Fail +sub;int;16;32;value;aarch64;Fail +sub;int;16;64;value;aarch64;Fail +sub;int;16;128;value;aarch64;Fail +sub;int;32;1;value;aarch64;Success; +sub;int;32;2;value;aarch64;Fail +sub;int;32;4;value;aarch64;Success; +sub;int;32;8;value;aarch64;Fail +sub;int;32;16;value;aarch64;Fail +sub;int;32;32;value;aarch64;Fail +sub;int;32;64;value;aarch64;Fail +sub;int;32;128;value;aarch64;Fail +sub;int;64;1;value;aarch64;Success; +sub;int;64;2;value;aarch64;Success; +sub;int;64;4;value;aarch64;Fail +sub;int;64;8;value;aarch64;Fail +sub;int;64;16;value;aarch64;Fail +sub;int;64;32;value;aarch64;Fail +sub;int;64;64;value;aarch64;Fail +sub;int;64;128;value;aarch64;Fail +div;int;8;1;value;aarch64;Success; +div;int;8;2;value;aarch64;Fail +div;int;8;4;value;aarch64;Fail +div;int;8;8;value;aarch64;Fail +div;int;8;16;value;aarch64;Fail +div;int;8;32;value;aarch64;Fail +div;int;8;64;value;aarch64;Fail +div;int;8;128;value;aarch64;Fail +div;int;16;1;value;aarch64;Success; +div;int;16;2;value;aarch64;Fail +div;int;16;4;value;aarch64;Fail +div;int;16;8;value;aarch64;Fail +div;int;16;16;value;aarch64;Fail +div;int;16;32;value;aarch64;Fail +div;int;16;64;value;aarch64;Fail +div;int;16;128;value;aarch64;Fail +div;int;32;1;value;aarch64;Success; +div;int;32;2;value;aarch64;Fail +div;int;32;4;value;aarch64;Fail +div;int;32;8;value;aarch64;Fail +div;int;32;16;value;aarch64;Fail +div;int;32;32;value;aarch64;Fail +div;int;32;64;value;aarch64;Fail +div;int;32;128;value;aarch64;Fail +div;int;64;1;value;aarch64;Success; +div;int;64;2;value;aarch64;Fail +div;int;64;4;value;aarch64;Fail +div;int;64;8;value;aarch64;Fail +div;int;64;16;value;aarch64;Fail +div;int;64;32;value;aarch64;Fail +div;int;64;64;value;aarch64;Fail +div;int;64;128;value;aarch64;Fail +add;flt;32;1;value;aarch64;Success; +add;flt;32;2;value;aarch64;Fail +add;flt;32;4;value;aarch64;Fail +add;flt;32;8;value;aarch64;Fail +add;flt;32;16;value;aarch64;Fail +add;flt;32;32;value;aarch64;Fail +add;flt;32;64;value;aarch64;Fail +add;flt;32;128;value;aarch64;Fail +add;flt;64;1;value;aarch64;Success; +add;flt;64;2;value;aarch64;Fail +add;flt;64;4;value;aarch64;Fail +add;flt;64;8;value;aarch64;Fail +add;flt;64;16;value;aarch64;Fail +add;flt;64;32;value;aarch64;Fail +add;flt;64;64;value;aarch64;Fail +add;flt;64;128;value;aarch64;Fail +mul;flt;32;1;value;aarch64;Success; +mul;flt;32;2;value;aarch64;Fail +mul;flt;32;4;value;aarch64;Fail +mul;flt;32;8;value;aarch64;Fail +mul;flt;32;16;value;aarch64;Fail +mul;flt;32;32;value;aarch64;Fail +mul;flt;32;64;value;aarch64;Fail +mul;flt;32;128;value;aarch64;Fail +mul;flt;64;1;value;aarch64;Success; +mul;flt;64;2;value;aarch64;Fail +mul;flt;64;4;value;aarch64;Fail +mul;flt;64;8;value;aarch64;Fail +mul;flt;64;16;value;aarch64;Fail +mul;flt;64;32;value;aarch64;Fail +mul;flt;64;64;value;aarch64;Fail +mul;flt;64;128;value;aarch64;Fail +sub;flt;32;1;value;aarch64;Success; +sub;flt;32;2;value;aarch64;Fail +sub;flt;32;4;value;aarch64;Fail +sub;flt;32;8;value;aarch64;Fail +sub;flt;32;16;value;aarch64;Fail +sub;flt;32;32;value;aarch64;Fail +sub;flt;32;64;value;aarch64;Fail +sub;flt;32;128;value;aarch64;Fail +sub;flt;64;1;value;aarch64;Success; +sub;flt;64;2;value;aarch64;Fail +sub;flt;64;4;value;aarch64;Fail +sub;flt;64;8;value;aarch64;Fail +sub;flt;64;16;value;aarch64;Fail +sub;flt;64;32;value;aarch64;Fail +sub;flt;64;64;value;aarch64;Fail +sub;flt;64;128;value;aarch64;Fail +div;flt;32;1;value;aarch64;Success; +div;flt;32;2;value;aarch64;Fail +div;flt;32;4;value;aarch64;Fail +div;flt;32;8;value;aarch64;Fail +div;flt;32;16;value;aarch64;Fail +div;flt;32;32;value;aarch64;Fail +div;flt;32;64;value;aarch64;Fail +div;flt;32;128;value;aarch64;Fail +div;flt;64;1;value;aarch64;Success; +div;flt;64;2;value;aarch64;Fail +div;flt;64;4;value;aarch64;Fail +div;flt;64;8;value;aarch64;Fail +div;flt;64;16;value;aarch64;Fail +div;flt;64;32;value;aarch64;Fail +div;flt;64;64;value;aarch64;Fail +div;flt;64;128;value;aarch64;Fail +mod;int;8;1;value;aarch64;Fail +mod;int;8;2;value;aarch64;Fail +mod;int;8;4;value;aarch64;Fail +mod;int;8;8;value;aarch64;Fail +mod;int;8;16;value;aarch64;Fail +mod;int;8;32;value;aarch64;Fail +mod;int;8;64;value;aarch64;Fail +mod;int;8;128;value;aarch64;Fail +mod;int;16;1;value;aarch64;Fail +mod;int;16;2;value;aarch64;Fail +mod;int;16;4;value;aarch64;Fail +mod;int;16;8;value;aarch64;Fail +mod;int;16;16;value;aarch64;Fail +mod;int;16;32;value;aarch64;Fail +mod;int;16;64;value;aarch64;Fail +mod;int;16;128;value;aarch64;Fail +mod;int;32;1;value;aarch64;Fail +mod;int;32;2;value;aarch64;Fail +mod;int;32;4;value;aarch64;Fail +mod;int;32;8;value;aarch64;Fail +mod;int;32;16;value;aarch64;Fail +mod;int;32;32;value;aarch64;Fail +mod;int;32;64;value;aarch64;Fail +mod;int;32;128;value;aarch64;Fail +mod;int;64;1;value;aarch64;Fail +mod;int;64;2;value;aarch64;Fail +mod;int;64;4;value;aarch64;Fail +mod;int;64;8;value;aarch64;Fail +mod;int;64;16;value;aarch64;Fail +mod;int;64;32;value;aarch64;Fail +mod;int;64;64;value;aarch64;Fail +mod;int;64;128;value;aarch64;Fail +or;int;8;1;value;aarch64;Success; +or;int;8;2;value;aarch64;Fail +or;int;8;4;value;aarch64;Fail +or;int;8;8;value;aarch64;Fail +or;int;8;16;value;aarch64;Fail +or;int;8;32;value;aarch64;Fail +or;int;8;64;value;aarch64;Fail +or;int;8;128;value;aarch64;Fail +or;int;16;1;value;aarch64;Success; +or;int;16;2;value;aarch64;Fail +or;int;16;4;value;aarch64;Success; +or;int;16;8;value;aarch64;Fail +or;int;16;16;value;aarch64;Fail +or;int;16;32;value;aarch64;Fail +or;int;16;64;value;aarch64;Fail +or;int;16;128;value;aarch64;Fail +or;int;32;1;value;aarch64;Success; +or;int;32;2;value;aarch64;Fail +or;int;32;4;value;aarch64;Success; +or;int;32;8;value;aarch64;Fail +or;int;32;16;value;aarch64;Fail +or;int;32;32;value;aarch64;Fail +or;int;32;64;value;aarch64;Fail +or;int;32;128;value;aarch64;Fail +or;int;64;1;value;aarch64;Success; +or;int;64;2;value;aarch64;Fail +or;int;64;4;value;aarch64;Fail +or;int;64;8;value;aarch64;Fail +or;int;64;16;value;aarch64;Fail +or;int;64;32;value;aarch64;Fail +or;int;64;64;value;aarch64;Fail +or;int;64;128;value;aarch64;Fail +and;int;8;1;value;aarch64;Success; +and;int;8;2;value;aarch64;Fail +and;int;8;4;value;aarch64;Fail +and;int;8;8;value;aarch64;Fail +and;int;8;16;value;aarch64;Fail +and;int;8;32;value;aarch64;Fail +and;int;8;64;value;aarch64;Fail +and;int;8;128;value;aarch64;Fail +and;int;16;1;value;aarch64;Success; +and;int;16;2;value;aarch64;Fail +and;int;16;4;value;aarch64;Success; +and;int;16;8;value;aarch64;Fail +and;int;16;16;value;aarch64;Fail +and;int;16;32;value;aarch64;Fail +and;int;16;64;value;aarch64;Fail +and;int;16;128;value;aarch64;Fail +and;int;32;1;value;aarch64;Success; +and;int;32;2;value;aarch64;Fail +and;int;32;4;value;aarch64;Success; +and;int;32;8;value;aarch64;Fail +and;int;32;16;value;aarch64;Fail +and;int;32;32;value;aarch64;Fail +and;int;32;64;value;aarch64;Fail +and;int;32;128;value;aarch64;Fail +and;int;64;1;value;aarch64;Success; +and;int;64;2;value;aarch64;Fail +and;int;64;4;value;aarch64;Fail +and;int;64;8;value;aarch64;Fail +and;int;64;16;value;aarch64;Fail +and;int;64;32;value;aarch64;Fail +and;int;64;64;value;aarch64;Fail +and;int;64;128;value;aarch64;Fail +xor;int;8;1;value;aarch64;Success; +xor;int;8;2;value;aarch64;Fail +xor;int;8;4;value;aarch64;Fail +xor;int;8;8;value;aarch64;Fail +xor;int;8;16;value;aarch64;Fail +xor;int;8;32;value;aarch64;Fail +xor;int;8;64;value;aarch64;Fail +xor;int;8;128;value;aarch64;Fail +xor;int;16;1;value;aarch64;Success; +xor;int;16;2;value;aarch64;Fail +xor;int;16;4;value;aarch64;Success; +xor;int;16;8;value;aarch64;Fail +xor;int;16;16;value;aarch64;Fail +xor;int;16;32;value;aarch64;Fail +xor;int;16;64;value;aarch64;Fail +xor;int;16;128;value;aarch64;Fail +xor;int;32;1;value;aarch64;Success; +xor;int;32;2;value;aarch64;Fail +xor;int;32;4;value;aarch64;Success; +xor;int;32;8;value;aarch64;Fail +xor;int;32;16;value;aarch64;Fail +xor;int;32;32;value;aarch64;Fail +xor;int;32;64;value;aarch64;Fail +xor;int;32;128;value;aarch64;Fail +xor;int;64;1;value;aarch64;Success; +xor;int;64;2;value;aarch64;Fail +xor;int;64;4;value;aarch64;Fail +xor;int;64;8;value;aarch64;Fail +xor;int;64;16;value;aarch64;Fail +xor;int;64;32;value;aarch64;Fail +xor;int;64;64;value;aarch64;Fail +xor;int;64;128;value;aarch64;Fail +sl;int;8;1;value;aarch64;Success; +sl;int;8;2;value;aarch64;Fail +sl;int;8;4;value;aarch64;Fail +sl;int;8;8;value;aarch64;Fail +sl;int;8;16;value;aarch64;Fail +sl;int;8;32;value;aarch64;Fail +sl;int;8;64;value;aarch64;Fail +sl;int;8;128;value;aarch64;Fail +sl;int;16;1;value;aarch64;Success; +sl;int;16;2;value;aarch64;Fail +sl;int;16;4;value;aarch64;Fail +sl;int;16;8;value;aarch64;Fail +sl;int;16;16;value;aarch64;Fail +sl;int;16;32;value;aarch64;Fail +sl;int;16;64;value;aarch64;Fail +sl;int;16;128;value;aarch64;Fail +sl;int;32;1;value;aarch64;Success; +sl;int;32;2;value;aarch64;Fail +sl;int;32;4;value;aarch64;Fail +sl;int;32;8;value;aarch64;Fail +sl;int;32;16;value;aarch64;Fail +sl;int;32;32;value;aarch64;Fail +sl;int;32;64;value;aarch64;Fail +sl;int;32;128;value;aarch64;Fail +sl;int;64;1;value;aarch64;Success; +sl;int;64;2;value;aarch64;Fail +sl;int;64;4;value;aarch64;Fail +sl;int;64;8;value;aarch64;Fail +sl;int;64;16;value;aarch64;Fail +sl;int;64;32;value;aarch64;Fail +sl;int;64;64;value;aarch64;Fail +sl;int;64;128;value;aarch64;Fail +sr;int;8;1;value;aarch64;Success; +sr;int;8;2;value;aarch64;Fail +sr;int;8;4;value;aarch64;Fail +sr;int;8;8;value;aarch64;Fail +sr;int;8;16;value;aarch64;Fail +sr;int;8;32;value;aarch64;Fail +sr;int;8;64;value;aarch64;Fail +sr;int;8;128;value;aarch64;Fail +sr;int;16;1;value;aarch64;Success; +sr;int;16;2;value;aarch64;Fail +sr;int;16;4;value;aarch64;Fail +sr;int;16;8;value;aarch64;Fail +sr;int;16;16;value;aarch64;Fail +sr;int;16;32;value;aarch64;Fail +sr;int;16;64;value;aarch64;Fail +sr;int;16;128;value;aarch64;Fail +sr;int;32;1;value;aarch64;Success; +sr;int;32;2;value;aarch64;Fail +sr;int;32;4;value;aarch64;Fail +sr;int;32;8;value;aarch64;Fail +sr;int;32;16;value;aarch64;Fail +sr;int;32;32;value;aarch64;Fail +sr;int;32;64;value;aarch64;Fail +sr;int;32;128;value;aarch64;Fail +sr;int;64;1;value;aarch64;Success; +sr;int;64;2;value;aarch64;Fail +sr;int;64;4;value;aarch64;Fail +sr;int;64;8;value;aarch64;Fail +sr;int;64;16;value;aarch64;Fail +sr;int;64;32;value;aarch64;Fail +sr;int;64;64;value;aarch64;Fail +sr;int;64;128;value;aarch64;Fail +add;int;8;1;value;riscv;Success; +add;int;8;2;value;riscv;Fail +add;int;8;4;value;riscv;Fail +add;int;8;8;value;riscv;Fail +add;int;8;16;value;riscv;Fail +add;int;8;32;value;riscv;Fail +add;int;8;64;value;riscv;Fail +add;int;8;128;value;riscv;Fail +add;int;16;1;value;riscv;Success; +add;int;16;2;value;riscv;Fail +add;int;16;4;value;riscv;Fail +add;int;16;8;value;riscv;Fail +add;int;16;16;value;riscv;Fail +add;int;16;32;value;riscv;Fail +add;int;16;64;value;riscv;Fail +add;int;16;128;value;riscv;Fail +add;int;32;1;value;riscv;Success; +add;int;32;2;value;riscv;Fail +add;int;32;4;value;riscv;Fail +add;int;32;8;value;riscv;Fail +add;int;32;16;value;riscv;Fail +add;int;32;32;value;riscv;Fail +add;int;32;64;value;riscv;Fail +add;int;32;128;value;riscv;Fail +add;int;64;1;value;riscv;Fail +add;int;64;2;value;riscv;Fail +add;int;64;4;value;riscv;Fail +add;int;64;8;value;riscv;Fail +add;int;64;16;value;riscv;Fail +add;int;64;32;value;riscv;Fail +add;int;64;64;value;riscv;Fail +add;int;64;128;value;riscv;Fail +mul;int;8;1;value;riscv;Success; +mul;int;8;2;value;riscv;Fail +mul;int;8;4;value;riscv;Fail +mul;int;8;8;value;riscv;Fail +mul;int;8;16;value;riscv;Fail +mul;int;8;32;value;riscv;Fail +mul;int;8;64;value;riscv;Fail +mul;int;8;128;value;riscv;Fail +mul;int;16;1;value;riscv;Success; +mul;int;16;2;value;riscv;Fail +mul;int;16;4;value;riscv;Fail +mul;int;16;8;value;riscv;Fail +mul;int;16;16;value;riscv;Fail +mul;int;16;32;value;riscv;Fail +mul;int;16;64;value;riscv;Fail +mul;int;16;128;value;riscv;Fail +mul;int;32;1;value;riscv;Success; +mul;int;32;2;value;riscv;Fail +mul;int;32;4;value;riscv;Fail +mul;int;32;8;value;riscv;Fail +mul;int;32;16;value;riscv;Fail +mul;int;32;32;value;riscv;Fail +mul;int;32;64;value;riscv;Fail +mul;int;32;128;value;riscv;Fail +mul;int;64;1;value;riscv;Fail +mul;int;64;2;value;riscv;Fail +mul;int;64;4;value;riscv;Fail +mul;int;64;8;value;riscv;Fail +mul;int;64;16;value;riscv;Fail +mul;int;64;32;value;riscv;Fail +mul;int;64;64;value;riscv;Fail +mul;int;64;128;value;riscv;Fail +sub;int;8;1;value;riscv;Success; +sub;int;8;2;value;riscv;Fail +sub;int;8;4;value;riscv;Fail +sub;int;8;8;value;riscv;Fail +sub;int;8;16;value;riscv;Fail +sub;int;8;32;value;riscv;Fail +sub;int;8;64;value;riscv;Fail +sub;int;8;128;value;riscv;Fail +sub;int;16;1;value;riscv;Success; +sub;int;16;2;value;riscv;Fail +sub;int;16;4;value;riscv;Fail +sub;int;16;8;value;riscv;Fail +sub;int;16;16;value;riscv;Fail +sub;int;16;32;value;riscv;Fail +sub;int;16;64;value;riscv;Fail +sub;int;16;128;value;riscv;Fail +sub;int;32;1;value;riscv;Success; +sub;int;32;2;value;riscv;Fail +sub;int;32;4;value;riscv;Fail +sub;int;32;8;value;riscv;Fail +sub;int;32;16;value;riscv;Fail +sub;int;32;32;value;riscv;Fail +sub;int;32;64;value;riscv;Fail +sub;int;32;128;value;riscv;Fail +sub;int;64;1;value;riscv;Fail +sub;int;64;2;value;riscv;Fail +sub;int;64;4;value;riscv;Fail +sub;int;64;8;value;riscv;Fail +sub;int;64;16;value;riscv;Fail +sub;int;64;32;value;riscv;Fail +sub;int;64;64;value;riscv;Fail +sub;int;64;128;value;riscv;Fail +div;int;8;1;value;riscv;Success; +div;int;8;2;value;riscv;Fail +div;int;8;4;value;riscv;Fail +div;int;8;8;value;riscv;Fail +div;int;8;16;value;riscv;Fail +div;int;8;32;value;riscv;Fail +div;int;8;64;value;riscv;Fail +div;int;8;128;value;riscv;Fail +div;int;16;1;value;riscv;Success; +div;int;16;2;value;riscv;Fail +div;int;16;4;value;riscv;Fail +div;int;16;8;value;riscv;Fail +div;int;16;16;value;riscv;Fail +div;int;16;32;value;riscv;Fail +div;int;16;64;value;riscv;Fail +div;int;16;128;value;riscv;Fail +div;int;32;1;value;riscv;Success; +div;int;32;2;value;riscv;Fail +div;int;32;4;value;riscv;Fail +div;int;32;8;value;riscv;Fail +div;int;32;16;value;riscv;Fail +div;int;32;32;value;riscv;Fail +div;int;32;64;value;riscv;Fail +div;int;32;128;value;riscv;Fail +div;int;64;1;value;riscv;Fail +div;int;64;2;value;riscv;Fail +div;int;64;4;value;riscv;Fail +div;int;64;8;value;riscv;Fail +div;int;64;16;value;riscv;Fail +div;int;64;32;value;riscv;Fail +div;int;64;64;value;riscv;Fail +div;int;64;128;value;riscv;Fail +add;flt;32;1;value;riscv;Success; +add;flt;32;2;value;riscv;Fail +add;flt;32;4;value;riscv;Fail +add;flt;32;8;value;riscv;Fail +add;flt;32;16;value;riscv;Fail +add;flt;32;32;value;riscv;Fail +add;flt;32;64;value;riscv;Fail +add;flt;32;128;value;riscv;Fail +add;flt;64;1;value;riscv;Success; +add;flt;64;2;value;riscv;Fail +add;flt;64;4;value;riscv;Fail +add;flt;64;8;value;riscv;Fail +add;flt;64;16;value;riscv;Fail +add;flt;64;32;value;riscv;Fail +add;flt;64;64;value;riscv;Fail +add;flt;64;128;value;riscv;Fail +mul;flt;32;1;value;riscv;Success; +mul;flt;32;2;value;riscv;Fail +mul;flt;32;4;value;riscv;Fail +mul;flt;32;8;value;riscv;Fail +mul;flt;32;16;value;riscv;Fail +mul;flt;32;32;value;riscv;Fail +mul;flt;32;64;value;riscv;Fail +mul;flt;32;128;value;riscv;Fail +mul;flt;64;1;value;riscv;Fail +mul;flt;64;2;value;riscv;Fail +mul;flt;64;4;value;riscv;Fail +mul;flt;64;8;value;riscv;Fail +mul;flt;64;16;value;riscv;Fail +mul;flt;64;32;value;riscv;Fail +mul;flt;64;64;value;riscv;Fail +mul;flt;64;128;value;riscv;Fail +sub;flt;32;1;value;riscv;Success; +sub;flt;32;2;value;riscv;Fail +sub;flt;32;4;value;riscv;Fail +sub;flt;32;8;value;riscv;Fail +sub;flt;32;16;value;riscv;Fail +sub;flt;32;32;value;riscv;Fail +sub;flt;32;64;value;riscv;Fail +sub;flt;32;128;value;riscv;Fail +sub;flt;64;1;value;riscv;Fail +sub;flt;64;2;value;riscv;Fail +sub;flt;64;4;value;riscv;Fail +sub;flt;64;8;value;riscv;Fail +sub;flt;64;16;value;riscv;Fail +sub;flt;64;32;value;riscv;Fail +sub;flt;64;64;value;riscv;Fail +sub;flt;64;128;value;riscv;Fail +div;flt;32;1;value;riscv;Success; +div;flt;32;2;value;riscv;Fail +div;flt;32;4;value;riscv;Fail +div;flt;32;8;value;riscv;Fail +div;flt;32;16;value;riscv;Fail +div;flt;32;32;value;riscv;Fail +div;flt;32;64;value;riscv;Fail +div;flt;32;128;value;riscv;Fail +div;flt;64;1;value;riscv;Success; +div;flt;64;2;value;riscv;Fail +div;flt;64;4;value;riscv;Fail +div;flt;64;8;value;riscv;Fail +div;flt;64;16;value;riscv;Fail +div;flt;64;32;value;riscv;Fail +div;flt;64;64;value;riscv;Fail +div;flt;64;128;value;riscv;Fail +mod;int;8;1;value;riscv;Fail +mod;int;8;2;value;riscv;Fail +mod;int;8;4;value;riscv;Fail +mod;int;8;8;value;riscv;Fail +mod;int;8;16;value;riscv;Fail +mod;int;8;32;value;riscv;Fail +mod;int;8;64;value;riscv;Fail +mod;int;8;128;value;riscv;Fail +mod;int;16;1;value;riscv;Fail +mod;int;16;2;value;riscv;Fail +mod;int;16;4;value;riscv;Fail +mod;int;16;8;value;riscv;Fail +mod;int;16;16;value;riscv;Fail +mod;int;16;32;value;riscv;Fail +mod;int;16;64;value;riscv;Fail +mod;int;16;128;value;riscv;Fail +mod;int;32;1;value;riscv;Fail +mod;int;32;2;value;riscv;Fail +mod;int;32;4;value;riscv;Fail +mod;int;32;8;value;riscv;Fail +mod;int;32;16;value;riscv;Fail +mod;int;32;32;value;riscv;Fail +mod;int;32;64;value;riscv;Fail +mod;int;32;128;value;riscv;Fail +mod;int;64;1;value;riscv;Fail +mod;int;64;2;value;riscv;Fail +mod;int;64;4;value;riscv;Fail +mod;int;64;8;value;riscv;Fail +mod;int;64;16;value;riscv;Fail +mod;int;64;32;value;riscv;Fail +mod;int;64;64;value;riscv;Fail +mod;int;64;128;value;riscv;Fail +or;int;8;1;value;riscv;Success; +or;int;8;2;value;riscv;Fail +or;int;8;4;value;riscv;Fail +or;int;8;8;value;riscv;Fail +or;int;8;16;value;riscv;Fail +or;int;8;32;value;riscv;Fail +or;int;8;64;value;riscv;Fail +or;int;8;128;value;riscv;Fail +or;int;16;1;value;riscv;Success; +or;int;16;2;value;riscv;Fail +or;int;16;4;value;riscv;Fail +or;int;16;8;value;riscv;Fail +or;int;16;16;value;riscv;Fail +or;int;16;32;value;riscv;Fail +or;int;16;64;value;riscv;Fail +or;int;16;128;value;riscv;Fail +or;int;32;1;value;riscv;Success; +or;int;32;2;value;riscv;Fail +or;int;32;4;value;riscv;Fail +or;int;32;8;value;riscv;Fail +or;int;32;16;value;riscv;Fail +or;int;32;32;value;riscv;Fail +or;int;32;64;value;riscv;Fail +or;int;32;128;value;riscv;Fail +or;int;64;1;value;riscv;Fail +or;int;64;2;value;riscv;Fail +or;int;64;4;value;riscv;Fail +or;int;64;8;value;riscv;Fail +or;int;64;16;value;riscv;Fail +or;int;64;32;value;riscv;Fail +or;int;64;64;value;riscv;Fail +or;int;64;128;value;riscv;Fail +and;int;8;1;value;riscv;Success; +and;int;8;2;value;riscv;Fail +and;int;8;4;value;riscv;Fail +and;int;8;8;value;riscv;Fail +and;int;8;16;value;riscv;Fail +and;int;8;32;value;riscv;Fail +and;int;8;64;value;riscv;Fail +and;int;8;128;value;riscv;Fail +and;int;16;1;value;riscv;Success; +and;int;16;2;value;riscv;Fail +and;int;16;4;value;riscv;Fail +and;int;16;8;value;riscv;Fail +and;int;16;16;value;riscv;Fail +and;int;16;32;value;riscv;Fail +and;int;16;64;value;riscv;Fail +and;int;16;128;value;riscv;Fail +and;int;32;1;value;riscv;Success; +and;int;32;2;value;riscv;Fail +and;int;32;4;value;riscv;Fail +and;int;32;8;value;riscv;Fail +and;int;32;16;value;riscv;Fail +and;int;32;32;value;riscv;Fail +and;int;32;64;value;riscv;Fail +and;int;32;128;value;riscv;Fail +and;int;64;1;value;riscv;Fail +and;int;64;2;value;riscv;Fail +and;int;64;4;value;riscv;Fail +and;int;64;8;value;riscv;Fail +and;int;64;16;value;riscv;Fail +and;int;64;32;value;riscv;Fail +and;int;64;64;value;riscv;Fail +and;int;64;128;value;riscv;Fail +xor;int;8;1;value;riscv;Success; +xor;int;8;2;value;riscv;Fail +xor;int;8;4;value;riscv;Fail +xor;int;8;8;value;riscv;Fail +xor;int;8;16;value;riscv;Fail +xor;int;8;32;value;riscv;Fail +xor;int;8;64;value;riscv;Fail +xor;int;8;128;value;riscv;Fail +xor;int;16;1;value;riscv;Success; +xor;int;16;2;value;riscv;Fail +xor;int;16;4;value;riscv;Fail +xor;int;16;8;value;riscv;Fail +xor;int;16;16;value;riscv;Fail +xor;int;16;32;value;riscv;Fail +xor;int;16;64;value;riscv;Fail +xor;int;16;128;value;riscv;Fail +xor;int;32;1;value;riscv;Success; +xor;int;32;2;value;riscv;Fail +xor;int;32;4;value;riscv;Fail +xor;int;32;8;value;riscv;Fail +xor;int;32;16;value;riscv;Fail +xor;int;32;32;value;riscv;Fail +xor;int;32;64;value;riscv;Fail +xor;int;32;128;value;riscv;Fail +xor;int;64;1;value;riscv;Fail +xor;int;64;2;value;riscv;Fail +xor;int;64;4;value;riscv;Fail +xor;int;64;8;value;riscv;Fail +xor;int;64;16;value;riscv;Fail +xor;int;64;32;value;riscv;Fail +xor;int;64;64;value;riscv;Fail +xor;int;64;128;value;riscv;Fail +sl;int;8;1;value;riscv;Success; +sl;int;8;2;value;riscv;Fail +sl;int;8;4;value;riscv;Fail +sl;int;8;8;value;riscv;Fail +sl;int;8;16;value;riscv;Fail +sl;int;8;32;value;riscv;Fail +sl;int;8;64;value;riscv;Fail +sl;int;8;128;value;riscv;Fail +sl;int;16;1;value;riscv;Success; +sl;int;16;2;value;riscv;Fail +sl;int;16;4;value;riscv;Fail +sl;int;16;8;value;riscv;Fail +sl;int;16;16;value;riscv;Fail +sl;int;16;32;value;riscv;Fail +sl;int;16;64;value;riscv;Fail +sl;int;16;128;value;riscv;Fail +sl;int;32;1;value;riscv;Success; +sl;int;32;2;value;riscv;Fail +sl;int;32;4;value;riscv;Fail +sl;int;32;8;value;riscv;Fail +sl;int;32;16;value;riscv;Fail +sl;int;32;32;value;riscv;Fail +sl;int;32;64;value;riscv;Fail +sl;int;32;128;value;riscv;Fail +sl;int;64;1;value;riscv;Fail +sl;int;64;2;value;riscv;Fail +sl;int;64;4;value;riscv;Fail +sl;int;64;8;value;riscv;Fail +sl;int;64;16;value;riscv;Fail +sl;int;64;32;value;riscv;Fail +sl;int;64;64;value;riscv;Fail +sl;int;64;128;value;riscv;Fail +sr;int;8;1;value;riscv;Success; +sr;int;8;2;value;riscv;Fail +sr;int;8;4;value;riscv;Fail +sr;int;8;8;value;riscv;Fail +sr;int;8;16;value;riscv;Fail +sr;int;8;32;value;riscv;Fail +sr;int;8;64;value;riscv;Fail +sr;int;8;128;value;riscv;Fail +sr;int;16;1;value;riscv;Success; +sr;int;16;2;value;riscv;Fail +sr;int;16;4;value;riscv;Fail +sr;int;16;8;value;riscv;Fail +sr;int;16;16;value;riscv;Fail +sr;int;16;32;value;riscv;Fail +sr;int;16;64;value;riscv;Fail +sr;int;16;128;value;riscv;Fail +sr;int;32;1;value;riscv;Success; +sr;int;32;2;value;riscv;Fail +sr;int;32;4;value;riscv;Fail +sr;int;32;8;value;riscv;Fail +sr;int;32;16;value;riscv;Fail +sr;int;32;32;value;riscv;Fail +sr;int;32;64;value;riscv;Fail +sr;int;32;128;value;riscv;Fail +sr;int;64;1;value;riscv;Fail +sr;int;64;2;value;riscv;Fail +sr;int;64;4;value;riscv;Fail +sr;int;64;8;value;riscv;Fail +sr;int;64;16;value;riscv;Fail +sr;int;64;32;value;riscv;Fail +sr;int;64;64;value;riscv;Fail +sr;int;64;128;value;riscv;Fail +add;int;8;1;value;power;Success; +add;int;8;2;value;power;Fail +add;int;8;4;value;power;Fail +add;int;8;8;value;power;Fail +add;int;8;16;value;power;Fail +add;int;8;32;value;power;Fail +add;int;8;64;value;power;Fail +add;int;8;128;value;power;Fail +add;int;16;1;value;power;Success; +add;int;16;2;value;power;Fail +add;int;16;4;value;power;Fail +add;int;16;8;value;power;Fail +add;int;16;16;value;power;Fail +add;int;16;32;value;power;Fail +add;int;16;64;value;power;Fail +add;int;16;128;value;power;Fail +add;int;32;1;value;power;Success; +add;int;32;2;value;power;Fail +add;int;32;4;value;power;Fail +add;int;32;8;value;power;Fail +add;int;32;16;value;power;Fail +add;int;32;32;value;power;Fail +add;int;32;64;value;power;Fail +add;int;32;128;value;power;Fail +add;int;64;1;value;power;Fail +add;int;64;2;value;power;Fail +add;int;64;4;value;power;Fail +add;int;64;8;value;power;Fail +add;int;64;16;value;power;Fail +add;int;64;32;value;power;Fail +add;int;64;64;value;power;Fail +add;int;64;128;value;power;Fail +mul;int;8;1;value;power;Success; +mul;int;8;2;value;power;Fail +mul;int;8;4;value;power;Fail +mul;int;8;8;value;power;Fail +mul;int;8;16;value;power;Fail +mul;int;8;32;value;power;Fail +mul;int;8;64;value;power;Fail +mul;int;8;128;value;power;Fail +mul;int;16;1;value;power;Success; +mul;int;16;2;value;power;Fail +mul;int;16;4;value;power;Fail +mul;int;16;8;value;power;Fail +mul;int;16;16;value;power;Fail +mul;int;16;32;value;power;Fail +mul;int;16;64;value;power;Fail +mul;int;16;128;value;power;Fail +mul;int;32;1;value;power;Success; +mul;int;32;2;value;power;Fail +mul;int;32;4;value;power;Fail +mul;int;32;8;value;power;Fail +mul;int;32;16;value;power;Fail +mul;int;32;32;value;power;Fail +mul;int;32;64;value;power;Fail +mul;int;32;128;value;power;Fail +mul;int;64;1;value;power;Fail +mul;int;64;2;value;power;Fail +mul;int;64;4;value;power;Fail +mul;int;64;8;value;power;Fail +mul;int;64;16;value;power;Fail +mul;int;64;32;value;power;Fail +mul;int;64;64;value;power;Fail +mul;int;64;128;value;power;Fail +sub;int;8;1;value;power;Success; +sub;int;8;2;value;power;Fail +sub;int;8;4;value;power;Fail +sub;int;8;8;value;power;Fail +sub;int;8;16;value;power;Fail +sub;int;8;32;value;power;Fail +sub;int;8;64;value;power;Fail +sub;int;8;128;value;power;Fail +sub;int;16;1;value;power;Success; +sub;int;16;2;value;power;Fail +sub;int;16;4;value;power;Fail +sub;int;16;8;value;power;Fail +sub;int;16;16;value;power;Fail +sub;int;16;32;value;power;Fail +sub;int;16;64;value;power;Fail +sub;int;16;128;value;power;Fail +sub;int;32;1;value;power;Success; +sub;int;32;2;value;power;Fail +sub;int;32;4;value;power;Fail +sub;int;32;8;value;power;Fail +sub;int;32;16;value;power;Fail +sub;int;32;32;value;power;Fail +sub;int;32;64;value;power;Fail +sub;int;32;128;value;power;Fail +sub;int;64;1;value;power;Fail +sub;int;64;2;value;power;Fail +sub;int;64;4;value;power;Fail +sub;int;64;8;value;power;Fail +sub;int;64;16;value;power;Fail +sub;int;64;32;value;power;Fail +sub;int;64;64;value;power;Fail +sub;int;64;128;value;power;Fail +div;int;8;1;value;power;Success; +div;int;8;2;value;power;Fail +div;int;8;4;value;power;Fail +div;int;8;8;value;power;Fail +div;int;8;16;value;power;Fail +div;int;8;32;value;power;Fail +div;int;8;64;value;power;Fail +div;int;8;128;value;power;Fail +div;int;16;1;value;power;Success; +div;int;16;2;value;power;Fail +div;int;16;4;value;power;Fail +div;int;16;8;value;power;Fail +div;int;16;16;value;power;Fail +div;int;16;32;value;power;Fail +div;int;16;64;value;power;Fail +div;int;16;128;value;power;Fail +div;int;32;1;value;power;Success; +div;int;32;2;value;power;Fail +div;int;32;4;value;power;Fail +div;int;32;8;value;power;Fail +div;int;32;16;value;power;Fail +div;int;32;32;value;power;Fail +div;int;32;64;value;power;Fail +div;int;32;128;value;power;Fail +div;int;64;1;value;power;Fail +div;int;64;2;value;power;Fail +div;int;64;4;value;power;Fail +div;int;64;8;value;power;Fail +div;int;64;16;value;power;Fail +div;int;64;32;value;power;Fail +div;int;64;64;value;power;Fail +div;int;64;128;value;power;Fail +add;flt;32;1;value;power;Success; +add;flt;32;2;value;power;Fail +add;flt;32;4;value;power;Fail +add;flt;32;8;value;power;Fail +add;flt;32;16;value;power;Fail +add;flt;32;32;value;power;Fail +add;flt;32;64;value;power;Fail +add;flt;32;128;value;power;Fail +add;flt;64;1;value;power;Success; +add;flt;64;2;value;power;Fail +add;flt;64;4;value;power;Fail +add;flt;64;8;value;power;Fail +add;flt;64;16;value;power;Fail +add;flt;64;32;value;power;Fail +add;flt;64;64;value;power;Fail +add;flt;64;128;value;power;Fail +mul;flt;32;1;value;power;Success; +mul;flt;32;2;value;power;Fail +mul;flt;32;4;value;power;Fail +mul;flt;32;8;value;power;Fail +mul;flt;32;16;value;power;Fail +mul;flt;32;32;value;power;Fail +mul;flt;32;64;value;power;Fail +mul;flt;32;128;value;power;Fail +mul;flt;64;1;value;power;Success; +mul;flt;64;2;value;power;Fail +mul;flt;64;4;value;power;Fail +mul;flt;64;8;value;power;Fail +mul;flt;64;16;value;power;Fail +mul;flt;64;32;value;power;Fail +mul;flt;64;64;value;power;Fail +mul;flt;64;128;value;power;Fail +sub;flt;32;1;value;power;Success; +sub;flt;32;2;value;power;Fail +sub;flt;32;4;value;power;Fail +sub;flt;32;8;value;power;Fail +sub;flt;32;16;value;power;Fail +sub;flt;32;32;value;power;Fail +sub;flt;32;64;value;power;Fail +sub;flt;32;128;value;power;Fail +sub;flt;64;1;value;power;Success; +sub;flt;64;2;value;power;Fail +sub;flt;64;4;value;power;Fail +sub;flt;64;8;value;power;Fail +sub;flt;64;16;value;power;Fail +sub;flt;64;32;value;power;Fail +sub;flt;64;64;value;power;Fail +sub;flt;64;128;value;power;Fail +div;flt;32;1;value;power;Success; +div;flt;32;2;value;power;Fail +div;flt;32;4;value;power;Fail +div;flt;32;8;value;power;Fail +div;flt;32;16;value;power;Fail +div;flt;32;32;value;power;Fail +div;flt;32;64;value;power;Fail +div;flt;32;128;value;power;Fail +div;flt;64;1;value;power;Success; +div;flt;64;2;value;power;Fail +div;flt;64;4;value;power;Fail +div;flt;64;8;value;power;Fail +div;flt;64;16;value;power;Fail +div;flt;64;32;value;power;Fail +div;flt;64;64;value;power;Fail +div;flt;64;128;value;power;Fail +mod;int;8;1;value;power;Fail +mod;int;8;2;value;power;Fail +mod;int;8;4;value;power;Fail +mod;int;8;8;value;power;Fail +mod;int;8;16;value;power;Fail +mod;int;8;32;value;power;Fail +mod;int;8;64;value;power;Fail +mod;int;8;128;value;power;Fail +mod;int;16;1;value;power;Fail +mod;int;16;2;value;power;Fail +mod;int;16;4;value;power;Fail +mod;int;16;8;value;power;Fail +mod;int;16;16;value;power;Fail +mod;int;16;32;value;power;Fail +mod;int;16;64;value;power;Fail +mod;int;16;128;value;power;Fail +mod;int;32;1;value;power;Fail +mod;int;32;2;value;power;Fail +mod;int;32;4;value;power;Fail +mod;int;32;8;value;power;Fail +mod;int;32;16;value;power;Fail +mod;int;32;32;value;power;Fail +mod;int;32;64;value;power;Fail +mod;int;32;128;value;power;Fail +mod;int;64;1;value;power;Fail +mod;int;64;2;value;power;Fail +mod;int;64;4;value;power;Fail +mod;int;64;8;value;power;Fail +mod;int;64;16;value;power;Fail +mod;int;64;32;value;power;Fail +mod;int;64;64;value;power;Fail +mod;int;64;128;value;power;Fail +or;int;8;1;value;power;Success; +or;int;8;2;value;power;Fail +or;int;8;4;value;power;Fail +or;int;8;8;value;power;Fail +or;int;8;16;value;power;Fail +or;int;8;32;value;power;Fail +or;int;8;64;value;power;Fail +or;int;8;128;value;power;Fail +or;int;16;1;value;power;Success; +or;int;16;2;value;power;Fail +or;int;16;4;value;power;Fail +or;int;16;8;value;power;Fail +or;int;16;16;value;power;Fail +or;int;16;32;value;power;Fail +or;int;16;64;value;power;Fail +or;int;16;128;value;power;Fail +or;int;32;1;value;power;Success; +or;int;32;2;value;power;Fail +or;int;32;4;value;power;Fail +or;int;32;8;value;power;Fail +or;int;32;16;value;power;Fail +or;int;32;32;value;power;Fail +or;int;32;64;value;power;Fail +or;int;32;128;value;power;Fail +or;int;64;1;value;power;Fail +or;int;64;2;value;power;Fail +or;int;64;4;value;power;Fail +or;int;64;8;value;power;Fail +or;int;64;16;value;power;Fail +or;int;64;32;value;power;Fail +or;int;64;64;value;power;Fail +or;int;64;128;value;power;Fail +and;int;8;1;value;power;Success; +and;int;8;2;value;power;Fail +and;int;8;4;value;power;Fail +and;int;8;8;value;power;Fail +and;int;8;16;value;power;Fail +and;int;8;32;value;power;Fail +and;int;8;64;value;power;Fail +and;int;8;128;value;power;Fail +and;int;16;1;value;power;Success; +and;int;16;2;value;power;Fail +and;int;16;4;value;power;Fail +and;int;16;8;value;power;Fail +and;int;16;16;value;power;Fail +and;int;16;32;value;power;Fail +and;int;16;64;value;power;Fail +and;int;16;128;value;power;Fail +and;int;32;1;value;power;Success; +and;int;32;2;value;power;Fail +and;int;32;4;value;power;Fail +and;int;32;8;value;power;Fail +and;int;32;16;value;power;Fail +and;int;32;32;value;power;Fail +and;int;32;64;value;power;Fail +and;int;32;128;value;power;Fail +and;int;64;1;value;power;Fail +and;int;64;2;value;power;Fail +and;int;64;4;value;power;Fail +and;int;64;8;value;power;Fail +and;int;64;16;value;power;Fail +and;int;64;32;value;power;Fail +and;int;64;64;value;power;Fail +and;int;64;128;value;power;Fail +xor;int;8;1;value;power;Success; +xor;int;8;2;value;power;Fail +xor;int;8;4;value;power;Fail +xor;int;8;8;value;power;Fail +xor;int;8;16;value;power;Fail +xor;int;8;32;value;power;Fail +xor;int;8;64;value;power;Fail +xor;int;8;128;value;power;Fail +xor;int;16;1;value;power;Success; +xor;int;16;2;value;power;Fail +xor;int;16;4;value;power;Fail +xor;int;16;8;value;power;Fail +xor;int;16;16;value;power;Fail +xor;int;16;32;value;power;Fail +xor;int;16;64;value;power;Fail +xor;int;16;128;value;power;Fail +xor;int;32;1;value;power;Success; +xor;int;32;2;value;power;Fail +xor;int;32;4;value;power;Fail +xor;int;32;8;value;power;Fail +xor;int;32;16;value;power;Fail +xor;int;32;32;value;power;Fail +xor;int;32;64;value;power;Fail +xor;int;32;128;value;power;Fail +xor;int;64;1;value;power;Fail +xor;int;64;2;value;power;Fail +xor;int;64;4;value;power;Fail +xor;int;64;8;value;power;Fail +xor;int;64;16;value;power;Fail +xor;int;64;32;value;power;Fail +xor;int;64;64;value;power;Fail +xor;int;64;128;value;power;Fail +sl;int;8;1;value;power;Success; +sl;int;8;2;value;power;Fail +sl;int;8;4;value;power;Fail +sl;int;8;8;value;power;Fail +sl;int;8;16;value;power;Fail +sl;int;8;32;value;power;Fail +sl;int;8;64;value;power;Fail +sl;int;8;128;value;power;Fail +sl;int;16;1;value;power;Success; +sl;int;16;2;value;power;Fail +sl;int;16;4;value;power;Fail +sl;int;16;8;value;power;Fail +sl;int;16;16;value;power;Fail +sl;int;16;32;value;power;Fail +sl;int;16;64;value;power;Fail +sl;int;16;128;value;power;Fail +sl;int;32;1;value;power;Success; +sl;int;32;2;value;power;Fail +sl;int;32;4;value;power;Fail +sl;int;32;8;value;power;Fail +sl;int;32;16;value;power;Fail +sl;int;32;32;value;power;Fail +sl;int;32;64;value;power;Fail +sl;int;32;128;value;power;Fail +sl;int;64;1;value;power;Fail +sl;int;64;2;value;power;Fail +sl;int;64;4;value;power;Fail +sl;int;64;8;value;power;Fail +sl;int;64;16;value;power;Fail +sl;int;64;32;value;power;Fail +sl;int;64;64;value;power;Fail +sl;int;64;128;value;power;Fail +sr;int;8;1;value;power;Fail +sr;int;8;2;value;power;Fail +sr;int;8;4;value;power;Fail +sr;int;8;8;value;power;Fail +sr;int;8;16;value;power;Fail +sr;int;8;32;value;power;Fail +sr;int;8;64;value;power;Fail +sr;int;8;128;value;power;Fail +sr;int;16;1;value;power;Fail +sr;int;16;2;value;power;Fail +sr;int;16;4;value;power;Fail +sr;int;16;8;value;power;Fail +sr;int;16;16;value;power;Fail +sr;int;16;32;value;power;Fail +sr;int;16;64;value;power;Fail +sr;int;16;128;value;power;Fail +sr;int;32;1;value;power;Fail +sr;int;32;2;value;power;Fail +sr;int;32;4;value;power;Fail +sr;int;32;8;value;power;Fail +sr;int;32;16;value;power;Fail +sr;int;32;32;value;power;Fail +sr;int;32;64;value;power;Fail +sr;int;32;128;value;power;Fail +sr;int;64;1;value;power;Fail +sr;int;64;2;value;power;Fail +sr;int;64;4;value;power;Fail +sr;int;64;8;value;power;Fail +sr;int;64;16;value;power;Fail +sr;int;64;32;value;power;Fail +sr;int;64;64;value;power;Fail +sr;int;64;128;value;power;Fail +add;int;8;1;address;aarch64;Fail +add;int;8;2;address;aarch64;Fail +add;int;8;4;address;aarch64;Fail +add;int;8;8;address;aarch64;Success; +add;int;8;16;address;aarch64;Success; +add;int;8;32;address;aarch64;Fail +add;int;8;64;address;aarch64;Fail +add;int;8;128;address;aarch64;Fail +add;int;16;1;address;aarch64;Fail +add;int;16;2;address;aarch64;Fail +add;int;16;4;address;aarch64;Success; +add;int;16;8;address;aarch64;Success; +add;int;16;16;address;aarch64;Fail +add;int;16;32;address;aarch64;Fail +add;int;16;64;address;aarch64;Fail +add;int;16;128;address;aarch64;Fail +add;int;32;1;address;aarch64;Fail +add;int;32;2;address;aarch64;Success; +add;int;32;4;address;aarch64;Success; +add;int;32;8;address;aarch64;Fail +add;int;32;16;address;aarch64;Fail +add;int;32;32;address;aarch64;Fail +add;int;32;64;address;aarch64;Fail +add;int;32;128;address;aarch64;Fail +add;int;64;1;address;aarch64;Fail +add;int;64;2;address;aarch64;Fail +add;int;64;4;address;aarch64;Fail +add;int;64;8;address;aarch64;Fail +add;int;64;16;address;aarch64;Fail +add;int;64;32;address;aarch64;Fail +add;int;64;64;address;aarch64;Fail +add;int;64;128;address;aarch64;Fail +mul;int;8;1;address;aarch64;Fail +mul;int;8;2;address;aarch64;Fail +mul;int;8;4;address;aarch64;Fail +mul;int;8;8;address;aarch64;Fail +mul;int;8;16;address;aarch64;Fail +mul;int;8;32;address;aarch64;Fail +mul;int;8;64;address;aarch64;Fail +mul;int;8;128;address;aarch64;Fail +mul;int;16;1;address;aarch64;Fail +mul;int;16;2;address;aarch64;Fail +mul;int;16;4;address;aarch64;Success; +mul;int;16;8;address;aarch64;Success; +mul;int;16;16;address;aarch64;Fail +mul;int;16;32;address;aarch64;Fail +mul;int;16;64;address;aarch64;Fail +mul;int;16;128;address;aarch64;Fail +mul;int;32;1;address;aarch64;Fail +mul;int;32;2;address;aarch64;Success; +mul;int;32;4;address;aarch64;Success; +mul;int;32;8;address;aarch64;Fail +mul;int;32;16;address;aarch64;Fail +mul;int;32;32;address;aarch64;Fail +mul;int;32;64;address;aarch64;Fail +mul;int;32;128;address;aarch64;Fail +mul;int;64;1;address;aarch64;Fail +mul;int;64;2;address;aarch64;Fail +mul;int;64;4;address;aarch64;Fail +mul;int;64;8;address;aarch64;Fail +mul;int;64;16;address;aarch64;Fail +mul;int;64;32;address;aarch64;Fail +mul;int;64;64;address;aarch64;Fail +mul;int;64;128;address;aarch64;Fail +sub;int;8;1;address;aarch64;Fail +sub;int;8;2;address;aarch64;Fail +sub;int;8;4;address;aarch64;Fail +sub;int;8;8;address;aarch64;Success; +sub;int;8;16;address;aarch64;Success; +sub;int;8;32;address;aarch64;Fail +sub;int;8;64;address;aarch64;Fail +sub;int;8;128;address;aarch64;Fail +sub;int;16;1;address;aarch64;Fail +sub;int;16;2;address;aarch64;Fail +sub;int;16;4;address;aarch64;Success; +sub;int;16;8;address;aarch64;Success; +sub;int;16;16;address;aarch64;Fail +sub;int;16;32;address;aarch64;Fail +sub;int;16;64;address;aarch64;Fail +sub;int;16;128;address;aarch64;Fail +sub;int;32;1;address;aarch64;Fail +sub;int;32;2;address;aarch64;Success; +sub;int;32;4;address;aarch64;Success; +sub;int;32;8;address;aarch64;Fail +sub;int;32;16;address;aarch64;Fail +sub;int;32;32;address;aarch64;Fail +sub;int;32;64;address;aarch64;Fail +sub;int;32;128;address;aarch64;Fail +sub;int;64;1;address;aarch64;Fail +sub;int;64;2;address;aarch64;Fail +sub;int;64;4;address;aarch64;Fail +sub;int;64;8;address;aarch64;Fail +sub;int;64;16;address;aarch64;Fail +sub;int;64;32;address;aarch64;Fail +sub;int;64;64;address;aarch64;Fail +sub;int;64;128;address;aarch64;Fail +div;int;8;1;address;aarch64;Fail +div;int;8;2;address;aarch64;Fail +div;int;8;4;address;aarch64;Fail +div;int;8;8;address;aarch64;Fail +div;int;8;16;address;aarch64;Fail +div;int;8;32;address;aarch64;Fail +div;int;8;64;address;aarch64;Fail +div;int;8;128;address;aarch64;Fail +div;int;16;1;address;aarch64;Fail +div;int;16;2;address;aarch64;Fail +div;int;16;4;address;aarch64;Fail +div;int;16;8;address;aarch64;Fail +div;int;16;16;address;aarch64;Fail +div;int;16;32;address;aarch64;Fail +div;int;16;64;address;aarch64;Fail +div;int;16;128;address;aarch64;Fail +div;int;32;1;address;aarch64;Fail +div;int;32;2;address;aarch64;Fail +div;int;32;4;address;aarch64;Fail +div;int;32;8;address;aarch64;Fail +div;int;32;16;address;aarch64;Fail +div;int;32;32;address;aarch64;Fail +div;int;32;64;address;aarch64;Fail +div;int;32;128;address;aarch64;Fail +div;int;64;1;address;aarch64;Fail +div;int;64;2;address;aarch64;Fail +div;int;64;4;address;aarch64;Fail +div;int;64;8;address;aarch64;Fail +div;int;64;16;address;aarch64;Fail +div;int;64;32;address;aarch64;Fail +div;int;64;64;address;aarch64;Fail +div;int;64;128;address;aarch64;Fail +add;flt;32;1;address;aarch64;Fail +add;flt;32;2;address;aarch64;Fail +add;flt;32;4;address;aarch64;Fail +add;flt;32;8;address;aarch64;Fail +add;flt;32;16;address;aarch64;Fail +add;flt;32;32;address;aarch64;Fail +add;flt;32;64;address;aarch64;Fail +add;flt;32;128;address;aarch64;Fail +add;flt;64;1;address;aarch64;Fail +add;flt;64;2;address;aarch64;Fail +add;flt;64;4;address;aarch64;Fail +add;flt;64;8;address;aarch64;Fail +add;flt;64;16;address;aarch64;Fail +add;flt;64;32;address;aarch64;Fail +add;flt;64;64;address;aarch64;Fail +add;flt;64;128;address;aarch64;Fail +mul;flt;32;1;address;aarch64;Fail +mul;flt;32;2;address;aarch64;Fail +mul;flt;32;4;address;aarch64;Fail +mul;flt;32;8;address;aarch64;Fail +mul;flt;32;16;address;aarch64;Fail +mul;flt;32;32;address;aarch64;Fail +mul;flt;32;64;address;aarch64;Fail +mul;flt;32;128;address;aarch64;Fail +mul;flt;64;1;address;aarch64;Fail +mul;flt;64;2;address;aarch64;Fail +mul;flt;64;4;address;aarch64;Fail +mul;flt;64;8;address;aarch64;Fail +mul;flt;64;16;address;aarch64;Fail +mul;flt;64;32;address;aarch64;Fail +mul;flt;64;64;address;aarch64;Fail +mul;flt;64;128;address;aarch64;Fail +sub;flt;32;1;address;aarch64;Fail +sub;flt;32;2;address;aarch64;Fail +sub;flt;32;4;address;aarch64;Fail +sub;flt;32;8;address;aarch64;Fail +sub;flt;32;16;address;aarch64;Fail +sub;flt;32;32;address;aarch64;Fail +sub;flt;32;64;address;aarch64;Fail +sub;flt;32;128;address;aarch64;Fail +sub;flt;64;1;address;aarch64;Fail +sub;flt;64;2;address;aarch64;Fail +sub;flt;64;4;address;aarch64;Fail +sub;flt;64;8;address;aarch64;Fail +sub;flt;64;16;address;aarch64;Fail +sub;flt;64;32;address;aarch64;Fail +sub;flt;64;64;address;aarch64;Fail +sub;flt;64;128;address;aarch64;Fail +div;flt;32;1;address;aarch64;Fail +div;flt;32;2;address;aarch64;Fail +div;flt;32;4;address;aarch64;Fail +div;flt;32;8;address;aarch64;Fail +div;flt;32;16;address;aarch64;Fail +div;flt;32;32;address;aarch64;Fail +div;flt;32;64;address;aarch64;Fail +div;flt;32;128;address;aarch64;Fail +div;flt;64;1;address;aarch64;Fail +div;flt;64;2;address;aarch64;Fail +div;flt;64;4;address;aarch64;Fail +div;flt;64;8;address;aarch64;Fail +div;flt;64;16;address;aarch64;Fail +div;flt;64;32;address;aarch64;Fail +div;flt;64;64;address;aarch64;Fail +div;flt;64;128;address;aarch64;Fail +mod;int;8;1;address;aarch64;Fail +mod;int;8;2;address;aarch64;Fail +mod;int;8;4;address;aarch64;Fail +mod;int;8;8;address;aarch64;Fail +mod;int;8;16;address;aarch64;Fail +mod;int;8;32;address;aarch64;Fail +mod;int;8;64;address;aarch64;Fail +mod;int;8;128;address;aarch64;Fail +mod;int;16;1;address;aarch64;Fail +mod;int;16;2;address;aarch64;Fail +mod;int;16;4;address;aarch64;Fail +mod;int;16;8;address;aarch64;Fail +mod;int;16;16;address;aarch64;Fail +mod;int;16;32;address;aarch64;Fail +mod;int;16;64;address;aarch64;Fail +mod;int;16;128;address;aarch64;Fail +mod;int;32;1;address;aarch64;Fail +mod;int;32;2;address;aarch64;Fail +mod;int;32;4;address;aarch64;Fail +mod;int;32;8;address;aarch64;Fail +mod;int;32;16;address;aarch64;Fail +mod;int;32;32;address;aarch64;Fail +mod;int;32;64;address;aarch64;Fail +mod;int;32;128;address;aarch64;Fail +mod;int;64;1;address;aarch64;Fail +mod;int;64;2;address;aarch64;Fail +mod;int;64;4;address;aarch64;Fail +mod;int;64;8;address;aarch64;Fail +mod;int;64;16;address;aarch64;Fail +mod;int;64;32;address;aarch64;Fail +mod;int;64;64;address;aarch64;Fail +mod;int;64;128;address;aarch64;Fail +or;int;8;1;address;aarch64;Fail +or;int;8;2;address;aarch64;Fail +or;int;8;4;address;aarch64;Fail +or;int;8;8;address;aarch64;Success; +or;int;8;16;address;aarch64;Success; +or;int;8;32;address;aarch64;Fail +or;int;8;64;address;aarch64;Fail +or;int;8;128;address;aarch64;Fail +or;int;16;1;address;aarch64;Fail +or;int;16;2;address;aarch64;Fail +or;int;16;4;address;aarch64;Success; +or;int;16;8;address;aarch64;Success; +or;int;16;16;address;aarch64;Fail +or;int;16;32;address;aarch64;Fail +or;int;16;64;address;aarch64;Fail +or;int;16;128;address;aarch64;Fail +or;int;32;1;address;aarch64;Fail +or;int;32;2;address;aarch64;Success; +or;int;32;4;address;aarch64;Success; +or;int;32;8;address;aarch64;Fail +or;int;32;16;address;aarch64;Fail +or;int;32;32;address;aarch64;Fail +or;int;32;64;address;aarch64;Fail +or;int;32;128;address;aarch64;Fail +or;int;64;1;address;aarch64;Fail +or;int;64;2;address;aarch64;Fail +or;int;64;4;address;aarch64;Fail +or;int;64;8;address;aarch64;Fail +or;int;64;16;address;aarch64;Fail +or;int;64;32;address;aarch64;Fail +or;int;64;64;address;aarch64;Fail +or;int;64;128;address;aarch64;Fail +and;int;8;1;address;aarch64;Fail +and;int;8;2;address;aarch64;Fail +and;int;8;4;address;aarch64;Fail +and;int;8;8;address;aarch64;Success; +and;int;8;16;address;aarch64;Success; +and;int;8;32;address;aarch64;Fail +and;int;8;64;address;aarch64;Fail +and;int;8;128;address;aarch64;Fail +and;int;16;1;address;aarch64;Fail +and;int;16;2;address;aarch64;Fail +and;int;16;4;address;aarch64;Success; +and;int;16;8;address;aarch64;Success; +and;int;16;16;address;aarch64;Fail +and;int;16;32;address;aarch64;Fail +and;int;16;64;address;aarch64;Fail +and;int;16;128;address;aarch64;Fail +and;int;32;1;address;aarch64;Fail +and;int;32;2;address;aarch64;Success; +and;int;32;4;address;aarch64;Success; +and;int;32;8;address;aarch64;Fail +and;int;32;16;address;aarch64;Fail +and;int;32;32;address;aarch64;Fail +and;int;32;64;address;aarch64;Fail +and;int;32;128;address;aarch64;Fail +and;int;64;1;address;aarch64;Fail +and;int;64;2;address;aarch64;Fail +and;int;64;4;address;aarch64;Fail +and;int;64;8;address;aarch64;Fail +and;int;64;16;address;aarch64;Fail +and;int;64;32;address;aarch64;Fail +and;int;64;64;address;aarch64;Fail +and;int;64;128;address;aarch64;Fail +xor;int;8;1;address;aarch64;Fail +xor;int;8;2;address;aarch64;Fail +xor;int;8;4;address;aarch64;Fail +xor;int;8;8;address;aarch64;Success; +xor;int;8;16;address;aarch64;Success; +xor;int;8;32;address;aarch64;Fail +xor;int;8;64;address;aarch64;Fail +xor;int;8;128;address;aarch64;Fail +xor;int;16;1;address;aarch64;Fail +xor;int;16;2;address;aarch64;Fail +xor;int;16;4;address;aarch64;Success; +xor;int;16;8;address;aarch64;Success; +xor;int;16;16;address;aarch64;Fail +xor;int;16;32;address;aarch64;Fail +xor;int;16;64;address;aarch64;Fail +xor;int;16;128;address;aarch64;Fail +xor;int;32;1;address;aarch64;Fail +xor;int;32;2;address;aarch64;Success; +xor;int;32;4;address;aarch64;Success; +xor;int;32;8;address;aarch64;Fail +xor;int;32;16;address;aarch64;Fail +xor;int;32;32;address;aarch64;Fail +xor;int;32;64;address;aarch64;Fail +xor;int;32;128;address;aarch64;Fail +xor;int;64;1;address;aarch64;Fail +xor;int;64;2;address;aarch64;Fail +xor;int;64;4;address;aarch64;Fail +xor;int;64;8;address;aarch64;Fail +xor;int;64;16;address;aarch64;Fail +xor;int;64;32;address;aarch64;Fail +xor;int;64;64;address;aarch64;Fail +xor;int;64;128;address;aarch64;Fail +sl;int;8;1;address;aarch64;Fail +sl;int;8;2;address;aarch64;Fail +sl;int;8;4;address;aarch64;Fail +sl;int;8;8;address;aarch64;Fail +sl;int;8;16;address;aarch64;Fail +sl;int;8;32;address;aarch64;Fail +sl;int;8;64;address;aarch64;Fail +sl;int;8;128;address;aarch64;Fail +sl;int;16;1;address;aarch64;Fail +sl;int;16;2;address;aarch64;Fail +sl;int;16;4;address;aarch64;Fail +sl;int;16;8;address;aarch64;Fail +sl;int;16;16;address;aarch64;Fail +sl;int;16;32;address;aarch64;Fail +sl;int;16;64;address;aarch64;Fail +sl;int;16;128;address;aarch64;Fail +sl;int;32;1;address;aarch64;Fail +sl;int;32;2;address;aarch64;Fail +sl;int;32;4;address;aarch64;Fail +sl;int;32;8;address;aarch64;Fail +sl;int;32;16;address;aarch64;Fail +sl;int;32;32;address;aarch64;Fail +sl;int;32;64;address;aarch64;Fail +sl;int;32;128;address;aarch64;Fail +sl;int;64;1;address;aarch64;Fail +sl;int;64;2;address;aarch64;Fail +sl;int;64;4;address;aarch64;Fail +sl;int;64;8;address;aarch64;Fail +sl;int;64;16;address;aarch64;Fail +sl;int;64;32;address;aarch64;Fail +sl;int;64;64;address;aarch64;Fail +sl;int;64;128;address;aarch64;Fail +sr;int;8;1;address;aarch64;Fail +sr;int;8;2;address;aarch64;Fail +sr;int;8;4;address;aarch64;Fail +sr;int;8;8;address;aarch64;Fail +sr;int;8;16;address;aarch64;Fail +sr;int;8;32;address;aarch64;Fail +sr;int;8;64;address;aarch64;Fail +sr;int;8;128;address;aarch64;Fail +sr;int;16;1;address;aarch64;Fail +sr;int;16;2;address;aarch64;Fail +sr;int;16;4;address;aarch64;Fail +sr;int;16;8;address;aarch64;Fail +sr;int;16;16;address;aarch64;Fail +sr;int;16;32;address;aarch64;Fail +sr;int;16;64;address;aarch64;Fail +sr;int;16;128;address;aarch64;Fail +sr;int;32;1;address;aarch64;Fail +sr;int;32;2;address;aarch64;Fail +sr;int;32;4;address;aarch64;Fail +sr;int;32;8;address;aarch64;Fail +sr;int;32;16;address;aarch64;Fail +sr;int;32;32;address;aarch64;Fail +sr;int;32;64;address;aarch64;Fail +sr;int;32;128;address;aarch64;Fail +sr;int;64;1;address;aarch64;Fail +sr;int;64;2;address;aarch64;Fail +sr;int;64;4;address;aarch64;Fail +sr;int;64;8;address;aarch64;Fail +sr;int;64;16;address;aarch64;Fail +sr;int;64;32;address;aarch64;Fail +sr;int;64;64;address;aarch64;Fail +sr;int;64;128;address;aarch64;Fail +add;int;8;1;address;riscv;Fail +add;int;8;2;address;riscv;Fail +add;int;8;4;address;riscv;Fail +add;int;8;8;address;riscv;Fail +add;int;8;16;address;riscv;Fail +add;int;8;32;address;riscv;Fail +add;int;8;64;address;riscv;Fail +add;int;8;128;address;riscv;Fail +add;int;16;1;address;riscv;Fail +add;int;16;2;address;riscv;Fail +add;int;16;4;address;riscv;Fail +add;int;16;8;address;riscv;Fail +add;int;16;16;address;riscv;Fail +add;int;16;32;address;riscv;Fail +add;int;16;64;address;riscv;Fail +add;int;16;128;address;riscv;Fail +add;int;32;1;address;riscv;Fail +add;int;32;2;address;riscv;Fail +add;int;32;4;address;riscv;Fail +add;int;32;8;address;riscv;Fail +add;int;32;16;address;riscv;Fail +add;int;32;32;address;riscv;Fail +add;int;32;64;address;riscv;Fail +add;int;32;128;address;riscv;Fail +add;int;64;1;address;riscv;Fail +add;int;64;2;address;riscv;Fail +add;int;64;4;address;riscv;Fail +add;int;64;8;address;riscv;Fail +add;int;64;16;address;riscv;Fail +add;int;64;32;address;riscv;Fail +add;int;64;64;address;riscv;Fail +add;int;64;128;address;riscv;Fail +mul;int;8;1;address;riscv;Fail +mul;int;8;2;address;riscv;Fail +mul;int;8;4;address;riscv;Fail +mul;int;8;8;address;riscv;Fail +mul;int;8;16;address;riscv;Fail +mul;int;8;32;address;riscv;Fail +mul;int;8;64;address;riscv;Fail +mul;int;8;128;address;riscv;Fail +mul;int;16;1;address;riscv;Fail +mul;int;16;2;address;riscv;Fail +mul;int;16;4;address;riscv;Fail +mul;int;16;8;address;riscv;Fail +mul;int;16;16;address;riscv;Fail +mul;int;16;32;address;riscv;Fail +mul;int;16;64;address;riscv;Fail +mul;int;16;128;address;riscv;Fail +mul;int;32;1;address;riscv;Fail +mul;int;32;2;address;riscv;Fail +mul;int;32;4;address;riscv;Fail +mul;int;32;8;address;riscv;Fail +mul;int;32;16;address;riscv;Fail +mul;int;32;32;address;riscv;Fail +mul;int;32;64;address;riscv;Fail +mul;int;32;128;address;riscv;Fail +mul;int;64;1;address;riscv;Fail +mul;int;64;2;address;riscv;Fail +mul;int;64;4;address;riscv;Fail +mul;int;64;8;address;riscv;Fail +mul;int;64;16;address;riscv;Fail +mul;int;64;32;address;riscv;Fail +mul;int;64;64;address;riscv;Fail +mul;int;64;128;address;riscv;Fail +sub;int;8;1;address;riscv;Fail +sub;int;8;2;address;riscv;Fail +sub;int;8;4;address;riscv;Fail +sub;int;8;8;address;riscv;Fail +sub;int;8;16;address;riscv;Fail +sub;int;8;32;address;riscv;Fail +sub;int;8;64;address;riscv;Fail +sub;int;8;128;address;riscv;Fail +sub;int;16;1;address;riscv;Fail +sub;int;16;2;address;riscv;Fail +sub;int;16;4;address;riscv;Fail +sub;int;16;8;address;riscv;Fail +sub;int;16;16;address;riscv;Fail +sub;int;16;32;address;riscv;Fail +sub;int;16;64;address;riscv;Fail +sub;int;16;128;address;riscv;Fail +sub;int;32;1;address;riscv;Fail +sub;int;32;2;address;riscv;Fail +sub;int;32;4;address;riscv;Fail +sub;int;32;8;address;riscv;Fail +sub;int;32;16;address;riscv;Fail +sub;int;32;32;address;riscv;Fail +sub;int;32;64;address;riscv;Fail +sub;int;32;128;address;riscv;Fail +sub;int;64;1;address;riscv;Fail +sub;int;64;2;address;riscv;Fail +sub;int;64;4;address;riscv;Fail +sub;int;64;8;address;riscv;Fail +sub;int;64;16;address;riscv;Fail +sub;int;64;32;address;riscv;Fail +sub;int;64;64;address;riscv;Fail +sub;int;64;128;address;riscv;Fail +div;int;8;1;address;riscv;Fail +div;int;8;2;address;riscv;Fail +div;int;8;4;address;riscv;Fail +div;int;8;8;address;riscv;Fail +div;int;8;16;address;riscv;Fail +div;int;8;32;address;riscv;Fail +div;int;8;64;address;riscv;Fail +div;int;8;128;address;riscv;Fail +div;int;16;1;address;riscv;Fail +div;int;16;2;address;riscv;Fail +div;int;16;4;address;riscv;Fail +div;int;16;8;address;riscv;Fail +div;int;16;16;address;riscv;Fail +div;int;16;32;address;riscv;Fail +div;int;16;64;address;riscv;Fail +div;int;16;128;address;riscv;Fail +div;int;32;1;address;riscv;Fail +div;int;32;2;address;riscv;Fail +div;int;32;4;address;riscv;Fail +div;int;32;8;address;riscv;Fail +div;int;32;16;address;riscv;Fail +div;int;32;32;address;riscv;Fail +div;int;32;64;address;riscv;Fail +div;int;32;128;address;riscv;Fail +div;int;64;1;address;riscv;Fail +div;int;64;2;address;riscv;Fail +div;int;64;4;address;riscv;Fail +div;int;64;8;address;riscv;Fail +div;int;64;16;address;riscv;Fail +div;int;64;32;address;riscv;Fail +div;int;64;64;address;riscv;Fail +div;int;64;128;address;riscv;Fail +add;flt;32;1;address;riscv;Fail +add;flt;32;2;address;riscv;Fail +add;flt;32;4;address;riscv;Fail +add;flt;32;8;address;riscv;Fail +add;flt;32;16;address;riscv;Fail +add;flt;32;32;address;riscv;Fail +add;flt;32;64;address;riscv;Fail +add;flt;32;128;address;riscv;Fail +add;flt;64;1;address;riscv;Fail +add;flt;64;2;address;riscv;Fail +add;flt;64;4;address;riscv;Fail +add;flt;64;8;address;riscv;Fail +add;flt;64;16;address;riscv;Fail +add;flt;64;32;address;riscv;Fail +add;flt;64;64;address;riscv;Fail +add;flt;64;128;address;riscv;Fail +mul;flt;32;1;address;riscv;Fail +mul;flt;32;2;address;riscv;Fail +mul;flt;32;4;address;riscv;Fail +mul;flt;32;8;address;riscv;Fail +mul;flt;32;16;address;riscv;Fail +mul;flt;32;32;address;riscv;Fail +mul;flt;32;64;address;riscv;Fail +mul;flt;32;128;address;riscv;Fail +mul;flt;64;1;address;riscv;Fail +mul;flt;64;2;address;riscv;Fail +mul;flt;64;4;address;riscv;Fail +mul;flt;64;8;address;riscv;Fail +mul;flt;64;16;address;riscv;Fail +mul;flt;64;32;address;riscv;Fail +mul;flt;64;64;address;riscv;Fail +mul;flt;64;128;address;riscv;Fail +sub;flt;32;1;address;riscv;Fail +sub;flt;32;2;address;riscv;Fail +sub;flt;32;4;address;riscv;Fail +sub;flt;32;8;address;riscv;Fail +sub;flt;32;16;address;riscv;Fail +sub;flt;32;32;address;riscv;Fail +sub;flt;32;64;address;riscv;Fail +sub;flt;32;128;address;riscv;Fail +sub;flt;64;1;address;riscv;Fail +sub;flt;64;2;address;riscv;Fail +sub;flt;64;4;address;riscv;Fail +sub;flt;64;8;address;riscv;Fail +sub;flt;64;16;address;riscv;Fail +sub;flt;64;32;address;riscv;Fail +sub;flt;64;64;address;riscv;Fail +sub;flt;64;128;address;riscv;Fail +div;flt;32;1;address;riscv;Fail +div;flt;32;2;address;riscv;Fail +div;flt;32;4;address;riscv;Fail +div;flt;32;8;address;riscv;Fail +div;flt;32;16;address;riscv;Fail +div;flt;32;32;address;riscv;Fail +div;flt;32;64;address;riscv;Fail +div;flt;32;128;address;riscv;Fail +div;flt;64;1;address;riscv;Fail +div;flt;64;2;address;riscv;Fail +div;flt;64;4;address;riscv;Fail +div;flt;64;8;address;riscv;Fail +div;flt;64;16;address;riscv;Fail +div;flt;64;32;address;riscv;Fail +div;flt;64;64;address;riscv;Fail +div;flt;64;128;address;riscv;Fail +mod;int;8;1;address;riscv;Fail +mod;int;8;2;address;riscv;Fail +mod;int;8;4;address;riscv;Fail +mod;int;8;8;address;riscv;Fail +mod;int;8;16;address;riscv;Fail +mod;int;8;32;address;riscv;Fail +mod;int;8;64;address;riscv;Fail +mod;int;8;128;address;riscv;Fail +mod;int;16;1;address;riscv;Fail +mod;int;16;2;address;riscv;Fail +mod;int;16;4;address;riscv;Fail +mod;int;16;8;address;riscv;Fail +mod;int;16;16;address;riscv;Fail +mod;int;16;32;address;riscv;Fail +mod;int;16;64;address;riscv;Fail +mod;int;16;128;address;riscv;Fail +mod;int;32;1;address;riscv;Fail +mod;int;32;2;address;riscv;Fail +mod;int;32;4;address;riscv;Fail +mod;int;32;8;address;riscv;Fail +mod;int;32;16;address;riscv;Fail +mod;int;32;32;address;riscv;Fail +mod;int;32;64;address;riscv;Fail +mod;int;32;128;address;riscv;Fail +mod;int;64;1;address;riscv;Fail +mod;int;64;2;address;riscv;Fail +mod;int;64;4;address;riscv;Fail +mod;int;64;8;address;riscv;Fail +mod;int;64;16;address;riscv;Fail +mod;int;64;32;address;riscv;Fail +mod;int;64;64;address;riscv;Fail +mod;int;64;128;address;riscv;Fail +or;int;8;1;address;riscv;Fail +or;int;8;2;address;riscv;Fail +or;int;8;4;address;riscv;Fail +or;int;8;8;address;riscv;Fail +or;int;8;16;address;riscv;Fail +or;int;8;32;address;riscv;Fail +or;int;8;64;address;riscv;Fail +or;int;8;128;address;riscv;Fail +or;int;16;1;address;riscv;Fail +or;int;16;2;address;riscv;Fail +or;int;16;4;address;riscv;Fail +or;int;16;8;address;riscv;Fail +or;int;16;16;address;riscv;Fail +or;int;16;32;address;riscv;Fail +or;int;16;64;address;riscv;Fail +or;int;16;128;address;riscv;Fail +or;int;32;1;address;riscv;Fail +or;int;32;2;address;riscv;Fail +or;int;32;4;address;riscv;Fail +or;int;32;8;address;riscv;Fail +or;int;32;16;address;riscv;Fail +or;int;32;32;address;riscv;Fail +or;int;32;64;address;riscv;Fail +or;int;32;128;address;riscv;Fail +or;int;64;1;address;riscv;Fail +or;int;64;2;address;riscv;Fail +or;int;64;4;address;riscv;Fail +or;int;64;8;address;riscv;Fail +or;int;64;16;address;riscv;Fail +or;int;64;32;address;riscv;Fail +or;int;64;64;address;riscv;Fail +or;int;64;128;address;riscv;Fail +and;int;8;1;address;riscv;Fail +and;int;8;2;address;riscv;Fail +and;int;8;4;address;riscv;Fail +and;int;8;8;address;riscv;Fail +and;int;8;16;address;riscv;Fail +and;int;8;32;address;riscv;Fail +and;int;8;64;address;riscv;Fail +and;int;8;128;address;riscv;Fail +and;int;16;1;address;riscv;Fail +and;int;16;2;address;riscv;Fail +and;int;16;4;address;riscv;Fail +and;int;16;8;address;riscv;Fail +and;int;16;16;address;riscv;Fail +and;int;16;32;address;riscv;Fail +and;int;16;64;address;riscv;Fail +and;int;16;128;address;riscv;Fail +and;int;32;1;address;riscv;Fail +and;int;32;2;address;riscv;Fail +and;int;32;4;address;riscv;Fail +and;int;32;8;address;riscv;Fail +and;int;32;16;address;riscv;Fail +and;int;32;32;address;riscv;Fail +and;int;32;64;address;riscv;Fail +and;int;32;128;address;riscv;Fail +and;int;64;1;address;riscv;Fail +and;int;64;2;address;riscv;Fail +and;int;64;4;address;riscv;Fail +and;int;64;8;address;riscv;Fail +and;int;64;16;address;riscv;Fail +and;int;64;32;address;riscv;Fail +and;int;64;64;address;riscv;Fail +and;int;64;128;address;riscv;Fail +xor;int;8;1;address;riscv;Fail +xor;int;8;2;address;riscv;Fail +xor;int;8;4;address;riscv;Fail +xor;int;8;8;address;riscv;Fail +xor;int;8;16;address;riscv;Fail +xor;int;8;32;address;riscv;Fail +xor;int;8;64;address;riscv;Fail +xor;int;8;128;address;riscv;Fail +xor;int;16;1;address;riscv;Fail +xor;int;16;2;address;riscv;Fail +xor;int;16;4;address;riscv;Fail +xor;int;16;8;address;riscv;Fail +xor;int;16;16;address;riscv;Fail +xor;int;16;32;address;riscv;Fail +xor;int;16;64;address;riscv;Fail +xor;int;16;128;address;riscv;Fail +xor;int;32;1;address;riscv;Fail +xor;int;32;2;address;riscv;Fail +xor;int;32;4;address;riscv;Fail +xor;int;32;8;address;riscv;Fail +xor;int;32;16;address;riscv;Fail +xor;int;32;32;address;riscv;Fail +xor;int;32;64;address;riscv;Fail +xor;int;32;128;address;riscv;Fail +xor;int;64;1;address;riscv;Fail +xor;int;64;2;address;riscv;Fail +xor;int;64;4;address;riscv;Fail +xor;int;64;8;address;riscv;Fail +xor;int;64;16;address;riscv;Fail +xor;int;64;32;address;riscv;Fail +xor;int;64;64;address;riscv;Fail +xor;int;64;128;address;riscv;Fail +sl;int;8;1;address;riscv;Fail +sl;int;8;2;address;riscv;Fail +sl;int;8;4;address;riscv;Fail +sl;int;8;8;address;riscv;Fail +sl;int;8;16;address;riscv;Fail +sl;int;8;32;address;riscv;Fail +sl;int;8;64;address;riscv;Fail +sl;int;8;128;address;riscv;Fail +sl;int;16;1;address;riscv;Fail +sl;int;16;2;address;riscv;Fail +sl;int;16;4;address;riscv;Fail +sl;int;16;8;address;riscv;Fail +sl;int;16;16;address;riscv;Fail +sl;int;16;32;address;riscv;Fail +sl;int;16;64;address;riscv;Fail +sl;int;16;128;address;riscv;Fail +sl;int;32;1;address;riscv;Fail +sl;int;32;2;address;riscv;Fail +sl;int;32;4;address;riscv;Fail +sl;int;32;8;address;riscv;Fail +sl;int;32;16;address;riscv;Fail +sl;int;32;32;address;riscv;Fail +sl;int;32;64;address;riscv;Fail +sl;int;32;128;address;riscv;Fail +sl;int;64;1;address;riscv;Fail +sl;int;64;2;address;riscv;Fail +sl;int;64;4;address;riscv;Fail +sl;int;64;8;address;riscv;Fail +sl;int;64;16;address;riscv;Fail +sl;int;64;32;address;riscv;Fail +sl;int;64;64;address;riscv;Fail +sl;int;64;128;address;riscv;Fail +sr;int;8;1;address;riscv;Fail +sr;int;8;2;address;riscv;Fail +sr;int;8;4;address;riscv;Fail +sr;int;8;8;address;riscv;Fail +sr;int;8;16;address;riscv;Fail +sr;int;8;32;address;riscv;Fail +sr;int;8;64;address;riscv;Fail +sr;int;8;128;address;riscv;Fail +sr;int;16;1;address;riscv;Fail +sr;int;16;2;address;riscv;Fail +sr;int;16;4;address;riscv;Fail +sr;int;16;8;address;riscv;Fail +sr;int;16;16;address;riscv;Fail +sr;int;16;32;address;riscv;Fail +sr;int;16;64;address;riscv;Fail +sr;int;16;128;address;riscv;Fail +sr;int;32;1;address;riscv;Fail +sr;int;32;2;address;riscv;Fail +sr;int;32;4;address;riscv;Fail +sr;int;32;8;address;riscv;Fail +sr;int;32;16;address;riscv;Fail +sr;int;32;32;address;riscv;Fail +sr;int;32;64;address;riscv;Fail +sr;int;32;128;address;riscv;Fail +sr;int;64;1;address;riscv;Fail +sr;int;64;2;address;riscv;Fail +sr;int;64;4;address;riscv;Fail +sr;int;64;8;address;riscv;Fail +sr;int;64;16;address;riscv;Fail +sr;int;64;32;address;riscv;Fail +sr;int;64;64;address;riscv;Fail +sr;int;64;128;address;riscv;Fail +add;int;8;1;address;power;Fail +add;int;8;2;address;power;Fail +add;int;8;4;address;power;Fail +add;int;8;8;address;power;Fail +add;int;8;16;address;power;Fail +add;int;8;32;address;power;Fail +add;int;8;64;address;power;Fail +add;int;8;128;address;power;Fail +add;int;16;1;address;power;Fail +add;int;16;2;address;power;Fail +add;int;16;4;address;power;Fail +add;int;16;8;address;power;Fail +add;int;16;16;address;power;Fail +add;int;16;32;address;power;Fail +add;int;16;64;address;power;Fail +add;int;16;128;address;power;Fail +add;int;32;1;address;power;Fail +add;int;32;2;address;power;Fail +add;int;32;4;address;power;Fail +add;int;32;8;address;power;Fail +add;int;32;16;address;power;Fail +add;int;32;32;address;power;Fail +add;int;32;64;address;power;Fail +add;int;32;128;address;power;Fail +add;int;64;1;address;power;Fail +add;int;64;2;address;power;Fail +add;int;64;4;address;power;Fail +add;int;64;8;address;power;Fail +add;int;64;16;address;power;Fail +add;int;64;32;address;power;Fail +add;int;64;64;address;power;Fail +add;int;64;128;address;power;Fail +mul;int;8;1;address;power;Fail +mul;int;8;2;address;power;Fail +mul;int;8;4;address;power;Fail +mul;int;8;8;address;power;Fail +mul;int;8;16;address;power;Fail +mul;int;8;32;address;power;Fail +mul;int;8;64;address;power;Fail +mul;int;8;128;address;power;Fail +mul;int;16;1;address;power;Fail +mul;int;16;2;address;power;Fail +mul;int;16;4;address;power;Fail +mul;int;16;8;address;power;Fail +mul;int;16;16;address;power;Fail +mul;int;16;32;address;power;Fail +mul;int;16;64;address;power;Fail +mul;int;16;128;address;power;Fail +mul;int;32;1;address;power;Fail +mul;int;32;2;address;power;Fail +mul;int;32;4;address;power;Fail +mul;int;32;8;address;power;Fail +mul;int;32;16;address;power;Fail +mul;int;32;32;address;power;Fail +mul;int;32;64;address;power;Fail +mul;int;32;128;address;power;Fail +mul;int;64;1;address;power;Fail +mul;int;64;2;address;power;Fail +mul;int;64;4;address;power;Fail +mul;int;64;8;address;power;Fail +mul;int;64;16;address;power;Fail +mul;int;64;32;address;power;Fail +mul;int;64;64;address;power;Fail +mul;int;64;128;address;power;Fail +sub;int;8;1;address;power;Fail +sub;int;8;2;address;power;Fail +sub;int;8;4;address;power;Fail +sub;int;8;8;address;power;Fail +sub;int;8;16;address;power;Fail +sub;int;8;32;address;power;Fail +sub;int;8;64;address;power;Fail +sub;int;8;128;address;power;Fail +sub;int;16;1;address;power;Fail +sub;int;16;2;address;power;Fail +sub;int;16;4;address;power;Fail +sub;int;16;8;address;power;Fail +sub;int;16;16;address;power;Fail +sub;int;16;32;address;power;Fail +sub;int;16;64;address;power;Fail +sub;int;16;128;address;power;Fail +sub;int;32;1;address;power;Fail +sub;int;32;2;address;power;Fail +sub;int;32;4;address;power;Fail +sub;int;32;8;address;power;Fail +sub;int;32;16;address;power;Fail +sub;int;32;32;address;power;Fail +sub;int;32;64;address;power;Fail +sub;int;32;128;address;power;Fail +sub;int;64;1;address;power;Fail +sub;int;64;2;address;power;Fail +sub;int;64;4;address;power;Fail +sub;int;64;8;address;power;Fail +sub;int;64;16;address;power;Fail +sub;int;64;32;address;power;Fail +sub;int;64;64;address;power;Fail +sub;int;64;128;address;power;Fail +div;int;8;1;address;power;Fail +div;int;8;2;address;power;Fail +div;int;8;4;address;power;Fail +div;int;8;8;address;power;Fail +div;int;8;16;address;power;Fail +div;int;8;32;address;power;Fail +div;int;8;64;address;power;Fail +div;int;8;128;address;power;Fail +div;int;16;1;address;power;Fail +div;int;16;2;address;power;Fail +div;int;16;4;address;power;Fail +div;int;16;8;address;power;Fail +div;int;16;16;address;power;Fail +div;int;16;32;address;power;Fail +div;int;16;64;address;power;Fail +div;int;16;128;address;power;Fail +div;int;32;1;address;power;Fail +div;int;32;2;address;power;Fail +div;int;32;4;address;power;Fail +div;int;32;8;address;power;Fail +div;int;32;16;address;power;Fail +div;int;32;32;address;power;Fail +div;int;32;64;address;power;Fail +div;int;32;128;address;power;Fail +div;int;64;1;address;power;Fail +div;int;64;2;address;power;Fail +div;int;64;4;address;power;Fail +div;int;64;8;address;power;Fail +div;int;64;16;address;power;Fail +div;int;64;32;address;power;Fail +div;int;64;64;address;power;Fail +div;int;64;128;address;power;Fail +add;flt;32;1;address;power;Fail +add;flt;32;2;address;power;Fail +add;flt;32;4;address;power;Fail +add;flt;32;8;address;power;Fail +add;flt;32;16;address;power;Fail +add;flt;32;32;address;power;Fail +add;flt;32;64;address;power;Fail +add;flt;32;128;address;power;Fail +add;flt;64;1;address;power;Fail +add;flt;64;2;address;power;Fail +add;flt;64;4;address;power;Fail +add;flt;64;8;address;power;Fail +add;flt;64;16;address;power;Fail +add;flt;64;32;address;power;Fail +add;flt;64;64;address;power;Fail +add;flt;64;128;address;power;Fail +mul;flt;32;1;address;power;Fail +mul;flt;32;2;address;power;Fail +mul;flt;32;4;address;power;Fail +mul;flt;32;8;address;power;Fail +mul;flt;32;16;address;power;Fail +mul;flt;32;32;address;power;Fail +mul;flt;32;64;address;power;Fail +mul;flt;32;128;address;power;Fail +mul;flt;64;1;address;power;Fail +mul;flt;64;2;address;power;Fail +mul;flt;64;4;address;power;Fail +mul;flt;64;8;address;power;Fail +mul;flt;64;16;address;power;Fail +mul;flt;64;32;address;power;Fail +mul;flt;64;64;address;power;Fail +mul;flt;64;128;address;power;Fail +sub;flt;32;1;address;power;Fail +sub;flt;32;2;address;power;Fail +sub;flt;32;4;address;power;Fail +sub;flt;32;8;address;power;Fail +sub;flt;32;16;address;power;Fail +sub;flt;32;32;address;power;Fail +sub;flt;32;64;address;power;Fail +sub;flt;32;128;address;power;Fail +sub;flt;64;1;address;power;Fail +sub;flt;64;2;address;power;Fail +sub;flt;64;4;address;power;Fail +sub;flt;64;8;address;power;Fail +sub;flt;64;16;address;power;Fail +sub;flt;64;32;address;power;Fail +sub;flt;64;64;address;power;Fail +sub;flt;64;128;address;power;Fail +div;flt;32;1;address;power;Fail +div;flt;32;2;address;power;Fail +div;flt;32;4;address;power;Fail +div;flt;32;8;address;power;Fail +div;flt;32;16;address;power;Fail +div;flt;32;32;address;power;Fail +div;flt;32;64;address;power;Fail +div;flt;32;128;address;power;Fail +div;flt;64;1;address;power;Fail +div;flt;64;2;address;power;Fail +div;flt;64;4;address;power;Fail +div;flt;64;8;address;power;Fail +div;flt;64;16;address;power;Fail +div;flt;64;32;address;power;Fail +div;flt;64;64;address;power;Fail +div;flt;64;128;address;power;Fail +mod;int;8;1;address;power;Fail +mod;int;8;2;address;power;Fail +mod;int;8;4;address;power;Fail +mod;int;8;8;address;power;Fail +mod;int;8;16;address;power;Fail +mod;int;8;32;address;power;Fail +mod;int;8;64;address;power;Fail +mod;int;8;128;address;power;Fail +mod;int;16;1;address;power;Fail +mod;int;16;2;address;power;Fail +mod;int;16;4;address;power;Fail +mod;int;16;8;address;power;Fail +mod;int;16;16;address;power;Fail +mod;int;16;32;address;power;Fail +mod;int;16;64;address;power;Fail +mod;int;16;128;address;power;Fail +mod;int;32;1;address;power;Fail +mod;int;32;2;address;power;Fail +mod;int;32;4;address;power;Fail +mod;int;32;8;address;power;Fail +mod;int;32;16;address;power;Fail +mod;int;32;32;address;power;Fail +mod;int;32;64;address;power;Fail +mod;int;32;128;address;power;Fail +mod;int;64;1;address;power;Fail +mod;int;64;2;address;power;Fail +mod;int;64;4;address;power;Fail +mod;int;64;8;address;power;Fail +mod;int;64;16;address;power;Fail +mod;int;64;32;address;power;Fail +mod;int;64;64;address;power;Fail +mod;int;64;128;address;power;Fail +or;int;8;1;address;power;Fail +or;int;8;2;address;power;Fail +or;int;8;4;address;power;Fail +or;int;8;8;address;power;Fail +or;int;8;16;address;power;Fail +or;int;8;32;address;power;Fail +or;int;8;64;address;power;Fail +or;int;8;128;address;power;Fail +or;int;16;1;address;power;Fail +or;int;16;2;address;power;Fail +or;int;16;4;address;power;Fail +or;int;16;8;address;power;Fail +or;int;16;16;address;power;Fail +or;int;16;32;address;power;Fail +or;int;16;64;address;power;Fail +or;int;16;128;address;power;Fail +or;int;32;1;address;power;Fail +or;int;32;2;address;power;Fail +or;int;32;4;address;power;Fail +or;int;32;8;address;power;Fail +or;int;32;16;address;power;Fail +or;int;32;32;address;power;Fail +or;int;32;64;address;power;Fail +or;int;32;128;address;power;Fail +or;int;64;1;address;power;Fail +or;int;64;2;address;power;Fail +or;int;64;4;address;power;Fail +or;int;64;8;address;power;Fail +or;int;64;16;address;power;Fail +or;int;64;32;address;power;Fail +or;int;64;64;address;power;Fail +or;int;64;128;address;power;Fail +and;int;8;1;address;power;Fail +and;int;8;2;address;power;Fail +and;int;8;4;address;power;Fail +and;int;8;8;address;power;Fail +and;int;8;16;address;power;Fail +and;int;8;32;address;power;Fail +and;int;8;64;address;power;Fail +and;int;8;128;address;power;Fail +and;int;16;1;address;power;Fail +and;int;16;2;address;power;Fail +and;int;16;4;address;power;Fail +and;int;16;8;address;power;Fail +and;int;16;16;address;power;Fail +and;int;16;32;address;power;Fail +and;int;16;64;address;power;Fail +and;int;16;128;address;power;Fail +and;int;32;1;address;power;Fail +and;int;32;2;address;power;Fail +and;int;32;4;address;power;Fail +and;int;32;8;address;power;Fail +and;int;32;16;address;power;Fail +and;int;32;32;address;power;Fail +and;int;32;64;address;power;Fail +and;int;32;128;address;power;Fail +and;int;64;1;address;power;Fail +and;int;64;2;address;power;Fail +and;int;64;4;address;power;Fail +and;int;64;8;address;power;Fail +and;int;64;16;address;power;Fail +and;int;64;32;address;power;Fail +and;int;64;64;address;power;Fail +and;int;64;128;address;power;Fail +xor;int;8;1;address;power;Fail +xor;int;8;2;address;power;Fail +xor;int;8;4;address;power;Fail +xor;int;8;8;address;power;Fail +xor;int;8;16;address;power;Fail +xor;int;8;32;address;power;Fail +xor;int;8;64;address;power;Fail +xor;int;8;128;address;power;Fail +xor;int;16;1;address;power;Fail +xor;int;16;2;address;power;Fail +xor;int;16;4;address;power;Fail +xor;int;16;8;address;power;Fail +xor;int;16;16;address;power;Fail +xor;int;16;32;address;power;Fail +xor;int;16;64;address;power;Fail +xor;int;16;128;address;power;Fail +xor;int;32;1;address;power;Fail +xor;int;32;2;address;power;Fail +xor;int;32;4;address;power;Fail +xor;int;32;8;address;power;Fail +xor;int;32;16;address;power;Fail +xor;int;32;32;address;power;Fail +xor;int;32;64;address;power;Fail +xor;int;32;128;address;power;Fail +xor;int;64;1;address;power;Fail +xor;int;64;2;address;power;Fail +xor;int;64;4;address;power;Fail +xor;int;64;8;address;power;Fail +xor;int;64;16;address;power;Fail +xor;int;64;32;address;power;Fail +xor;int;64;64;address;power;Fail +xor;int;64;128;address;power;Fail +sl;int;8;1;address;power;Fail +sl;int;8;2;address;power;Fail +sl;int;8;4;address;power;Fail +sl;int;8;8;address;power;Fail +sl;int;8;16;address;power;Fail +sl;int;8;32;address;power;Fail +sl;int;8;64;address;power;Fail +sl;int;8;128;address;power;Fail +sl;int;16;1;address;power;Fail +sl;int;16;2;address;power;Fail +sl;int;16;4;address;power;Fail +sl;int;16;8;address;power;Fail +sl;int;16;16;address;power;Fail +sl;int;16;32;address;power;Fail +sl;int;16;64;address;power;Fail +sl;int;16;128;address;power;Fail +sl;int;32;1;address;power;Fail +sl;int;32;2;address;power;Fail +sl;int;32;4;address;power;Fail +sl;int;32;8;address;power;Fail +sl;int;32;16;address;power;Fail +sl;int;32;32;address;power;Fail +sl;int;32;64;address;power;Fail +sl;int;32;128;address;power;Fail +sl;int;64;1;address;power;Fail +sl;int;64;2;address;power;Fail +sl;int;64;4;address;power;Fail +sl;int;64;8;address;power;Fail +sl;int;64;16;address;power;Fail +sl;int;64;32;address;power;Fail +sl;int;64;64;address;power;Fail +sl;int;64;128;address;power;Fail +sr;int;8;1;address;power;Fail +sr;int;8;2;address;power;Fail +sr;int;8;4;address;power;Fail +sr;int;8;8;address;power;Fail +sr;int;8;16;address;power;Fail +sr;int;8;32;address;power;Fail +sr;int;8;64;address;power;Fail +sr;int;8;128;address;power;Fail +sr;int;16;1;address;power;Fail +sr;int;16;2;address;power;Fail +sr;int;16;4;address;power;Fail +sr;int;16;8;address;power;Fail +sr;int;16;16;address;power;Fail +sr;int;16;32;address;power;Fail +sr;int;16;64;address;power;Fail +sr;int;16;128;address;power;Fail +sr;int;32;1;address;power;Fail +sr;int;32;2;address;power;Fail +sr;int;32;4;address;power;Fail +sr;int;32;8;address;power;Fail +sr;int;32;16;address;power;Fail +sr;int;32;32;address;power;Fail +sr;int;32;64;address;power;Fail +sr;int;32;128;address;power;Fail +sr;int;64;1;address;power;Fail +sr;int;64;2;address;power;Fail +sr;int;64;4;address;power;Fail +sr;int;64;8;address;power;Fail +sr;int;64;16;address;power;Fail +sr;int;64;32;address;power;Fail +sr;int;64;64;address;power;Fail +sr;int;64;128;address;power;Fail diff --git a/Demos/Makefile b/Demos/Makefile index 5d42c6e..10ec8cb 100644 --- a/Demos/Makefile +++ b/Demos/Makefile @@ -1,3 +1,17 @@ +buildAll: + -(cd Stencil; make buildAll) + -(cd VectorMatrix; make buildAll) + -(cd Newton-SquareRoot-VariablePrecision; make buildAll) + -(cd AudioFilter ; make buildAll) + -(cd C-SRAM_Applications; make buildAll) + -(cd CelciusFarenheitConversions; make buildAll) + -(cd ImagePixelSum; make buildAll) + -(cd IOTWorkerSpecialization; make buildAll) + -(cd Kahan3Sum; make buildAll) + -(cd ReversePolishNotation; make buildAll) + -(cd Stencil1D; make buildAll) + + clean: -(cd Stencil; make clean) -(cd VectorMatrix; make clean) diff --git a/Demos/Newton-SquareRoot-VariablePrecision/Newton.c b/Demos/Newton-SquareRoot-VariablePrecision/Newton.c new file mode 100644 index 0000000..d18ae26 --- /dev/null +++ b/Demos/Newton-SquareRoot-VariablePrecision/Newton.c @@ -0,0 +1,925 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +void RV32I_RET__I_32_1(){ /* RET */ + riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_RET__I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_ADDI_RRI_I_32_1(int r1,int r0,int i0){ /* ADD */ + riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_ADDI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_ADD_RRR_I_32_1(int r3,int r1,int r2){ /* ADD */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_ADD_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SUB_RRR_I_32_1(int r3,int r1,int r2){ /* SUB */ + riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SUB_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_MV_RR_I_32_1(int r0,int r1){ /* MV */ + riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_MV_RR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_MV_RI_I_32_1(int r3,int i1){ /* MV */ + riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_MV_RI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32F_FMV_S_RR_F_32_1(int r3,int r1){ /* MV */ + riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32F_FMV_S_RR_F_32_1\n", h2_asm_pc); +#endif +} +void RV32D_FMV_D_RR_F_64_1(int r3,int r1){ /* MV */ + riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32D_FMV_D_RR_F_64_1\n", h2_asm_pc); +#endif +} +void RV32I_LB_RRI_I_8_1(int r3,int r1,int i1){ /* R */ + riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_LB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void RV32I_LH_RRI_I_16_1(int r3,int r1,int i1){ /* R */ + riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_LH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void RV32I_LW_RRI_I_32_1(int r3,int r1,int i1){ /* R */ + riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_LW_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32F_FADD_S_RRR_F_32_1(int r3,int r1,int r2){ /* ADD */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32F_FADD_S_RRR_F_32_1\n", h2_asm_pc); +#endif +} +void RV32D_FADD_D_RRR_F_64_1(int r3,int r1,int r2){ /* ADD */ + riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32D_FADD_D_RRR_F_64_1\n", h2_asm_pc); +#endif +} +void RV32I_SLLI_RRI_I_32_1(int r3,int r1,int i0){ /* SL */ + riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SLLI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SLL_RRR_I_32_1(int r3,int r1,int r2){ /* SL */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SLL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32F_FDIV_S_RRR_F_32_1(int r3,int r1,int r2){ /* DIV */ + riscv_G32(((0xc & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32F_FDIV_S_RRR_F_32_1\n", h2_asm_pc); +#endif +} +void RV32D_FDIV_D_RRR_F_64_1(int r3,int r1,int r2){ /* DIV */ + riscv_G32(((0xd & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32D_FDIV_D_RRR_F_64_1\n", h2_asm_pc); +#endif +} +void RV32I_SRLI_RRI_I_32_1(int r3,int r1,int i0){ /* SR */ + riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SRLI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SRL_RRR_I_32_1(int r3,int r1,int r2){ /* SR */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SRL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SB_RRI_I_8_1(int r1,int r2,int i1){ /* W */ + riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void RV32I_SH_RRI_I_16_1(int r1,int r2,int i1){ /* W */ + riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void RV32I_SW_RRI_I_32_1(int r1,int r2,int i1){ /* W */ + riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SW_RRI_I_32_1\n", h2_asm_pc); +#endif +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FDIV_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32D_FDIV_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32F_FADD_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32D_FADD_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +/* -*- c -*- */ + +#include +#include +#include + + +#define True 1 +#define False 0 +#define FLOAT 32 +#define DOUBLE 64 + +typedef float (*piff)(float, float, float); +typedef double (*pidd)(double, double, double); +/* Newton square root demonstration with variable precision */ +h2_insn_t * genIterate(h2_insn_t * ptr, int FloatWidth) +{ + /* Code Generation of 4 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t u = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; + h2_sValue_t val = {H2REGISTER, 'f', 1, (FloatWidth), 11, true}; + h2_sValue_t div = {H2REGISTER, 'f', 1, (FloatWidth), 12, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; + h2_sValue_t tmp1 = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; + h2_sValue_t tmp2 = {H2REGISTER, 'f', 1, (FloatWidth), 2, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x31F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp1 = riscv_genDIV_4(tmp1, val, u, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp2 = riscv_genADD_3(tmp2, u, tmp1); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = riscv_genDIV_4(tmp0000, tmp2, div, immValueZero); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + /* r = (u + (#(value) / u)) / 2.0*/ + + return (h2_insn_t *) ptr; +} + +#define ABS(x) ((x < 0) ? -(x) : (x)) + +int main(int argc, char **argv) +{ + int isFloat, iterationNumber; + double af, precf, precd, value, next, diff; + piff fPtr1; + pidd fPtr2; + h2_insn_t * ptr; + char input; + if (argc < 3) + { + printf ("Newton \n"); + exit(-1); + } + iterationNumber = 0; + af = atof (argv[1]); + precd = atof (argv[2]); + precf = 1; // precd * 1.e14; + ptr = h2_malloc (1024); + isFloat = True; + printf ("Compute square root of %f\n", af); + printf ("With precision of %e (float)\n", precf); + printf ("With precision of %e (double)\n", precd); + next = 1.0; + diff = af; + + fPtr1 = (piff) genIterate (ptr, FLOAT); + do + { + if ((diff < precf) && isFloat) + { /* Code re-generation with double for better precision */ + fPtr2 = (pidd) genIterate (ptr, DOUBLE); + isFloat = False; + } + value = next; + next = (isFloat)?fPtr1(value, af, 2.0):fPtr2(value, af, 2.0); + diff = ABS(next - value); + printf("%3d %s : %.20f, %e\n", + iterationNumber++, + isFloat?"float ":"double", + next, isFloat?precf:precd); + + if(iterationNumber > 100){ + return -1; + } + } while ( diff > precd); + if(isFloat){ + return (next != sqrtf(af)) ? -1 : 0; + } + else{ + return (next != sqrt(af)) ? -1 : 0; + } +} diff --git a/Demos/Newton-SquareRoot-VariablePrecision/Newton.riscv b/Demos/Newton-SquareRoot-VariablePrecision/Newton.riscv new file mode 100755 index 0000000000000000000000000000000000000000..671c4acab69894ef561e7a5042da5600c1936973 GIT binary patch literal 65000 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 Xh8xA~X$ChbwtM=zb9GB3&4T{}x?h_3 literal 0 HcmV?d00001 diff --git a/Demos/Stencil/Stencil.aarch64 b/Demos/Stencil/Stencil.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..abf8305e08911bde0a495f8f6f93e6d20d69f94d GIT binary patch literal 86152 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 pxy)x_=u~%x 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 qN2u&a#br`Yl!$qT{zanv8xqu?BjH5k +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +// X * NPowerOf2 = X >> N (immediate shift left) +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSR_3(P0, P1, P2); + } +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (aarch64)\\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include +#include +#include +#include "ReadPgmImage.h" + +typedef int (*pifc)(int[], int, int, int); + + +void printImage(imgStruct_t *img, char *imageName) +{ + printf ("ImageName & size: %s %dx%d\n", imageName, img->height, img->width); + for(int line = 0 ; line < img->height ; line++) + { + for(int column = 0 ; column < img->width ; column++) + { + printf("%03d ", img->pixelsArray[line*img->width+column]); + } + printf("\n"); + } + printf("\n"); +} + +int imgSum (imgStruct_t *img) +{ + int line, column, sum; + sum = 0; + for(int line = 0 ; line < img->height ; line++) + { + for(int column = 0 ; column < img->width; column++) + { + sum += img->pixelsArray[line*img->width+column]; + } + } + return (0 == sum)?1:sum; +} + +#if 0 +unsigned char clamp(int value) +{ + return (unsigned char)(0 > value)?0:(255 < value)?255:value; +} +#else +#define clamp(value) ((unsigned char)(0 > value)?0:(255 < value)?255:value) +#endif + +pifc genKernel1x1(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 2, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF030F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, line, imgWidth); + tmp0001 = aarch64_genADD_3(tmp0001, tmp0000, column); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = aarch64_genMUL_3(tmp0002, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = aarch64_genADD_3(tmp0003, In, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = aarch64_genR_3(tmp0004, tmp0003, immValueZero); + sum = aarch64_genMUL_3(sum, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); + if (!sum.dontFree) h2_freeReg(tmp0004.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0005 = aarch64_genDIV_3(tmp0005, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0005, immValueZero); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +pifc genKernel3x3(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 19 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 2, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 13, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF3F0F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + njp1 = aarch64_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njm1 = aarch64_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = aarch64_genADD_3(tmp0000, stride, njm1); + tmp0001 = aarch64_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = aarch64_genADD_3(tmp0002, In, tmp0001); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = aarch64_genR_3(tmp0003, tmp0002, immValueZero); + sum = aarch64_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); + if (!sum.dontFree) h2_freeReg(tmp0003.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0004 = aarch64_genADD_3(tmp0004, stride, column); + tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = aarch64_genADD_3(tmp0006, In, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = aarch64_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = aarch64_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1]))}); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0008); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0009 = aarch64_genADD_3(tmp0009, stride, njp1); + tmp0010 = aarch64_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = aarch64_genADD_3(tmp0011, In, tmp0010); + if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); + tmp0012 = aarch64_genR_3(tmp0012, tmp0011, immValueZero); + tmp0013 = aarch64_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2]))}); + if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0013); + if (!sum.dontFree) h2_freeReg(tmp0013.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genMV_3(ni, line, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0015 = aarch64_genADD_3(tmp0015, stride, njm1); + tmp0016 = aarch64_genMUL_3(tmp0016, tmp0015, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); + tmp0017 = aarch64_genADD_3(tmp0017, In, tmp0016); + if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); + tmp0018 = aarch64_genR_3(tmp0018, tmp0017, immValueZero); + tmp0019 = aarch64_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+0]))}); + if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0019); + if (!sum.dontFree) h2_freeReg(tmp0019.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0020 = aarch64_genADD_3(tmp0020, stride, column); + tmp0021 = aarch64_genMUL_3(tmp0021, tmp0020, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); + tmp0022 = aarch64_genADD_3(tmp0022, In, tmp0021); + if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); + tmp0023 = aarch64_genR_3(tmp0023, tmp0022, immValueZero); + tmp0024 = aarch64_genMUL_3(tmp0024, tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+1]))}); + if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0024); + if (!sum.dontFree) h2_freeReg(tmp0024.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0025 = aarch64_genADD_3(tmp0025, stride, njp1); + tmp0026 = aarch64_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = aarch64_genADD_3(tmp0027, In, tmp0026); + if (!tmp0027.dontFree) h2_freeReg(tmp0026.regNro); + tmp0028 = aarch64_genR_3(tmp0028, tmp0027, immValueZero); + tmp0029 = aarch64_genMUL_3(tmp0029, tmp0028, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+2]))}); + if (!tmp0029.dontFree) h2_freeReg(tmp0028.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0029); + if (!sum.dontFree) h2_freeReg(tmp0029.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0030 = aarch64_genADD_3(tmp0030, stride, njm1); + tmp0031 = aarch64_genMUL_3(tmp0031, tmp0030, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = aarch64_genADD_3(tmp0032, In, tmp0031); + if (!tmp0032.dontFree) h2_freeReg(tmp0031.regNro); + tmp0033 = aarch64_genR_3(tmp0033, tmp0032, immValueZero); + tmp0034 = aarch64_genMUL_3(tmp0034, tmp0033, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+0]))}); + if (!tmp0034.dontFree) h2_freeReg(tmp0033.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0034); + if (!sum.dontFree) h2_freeReg(tmp0034.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0035 = aarch64_genADD_3(tmp0035, stride, column); + tmp0036 = aarch64_genMUL_3(tmp0036, tmp0035, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = aarch64_genADD_3(tmp0037, In, tmp0036); + if (!tmp0037.dontFree) h2_freeReg(tmp0036.regNro); + tmp0038 = aarch64_genR_3(tmp0038, tmp0037, immValueZero); + tmp0039 = aarch64_genMUL_3(tmp0039, tmp0038, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+1]))}); + if (!tmp0039.dontFree) h2_freeReg(tmp0038.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0039); + if (!sum.dontFree) h2_freeReg(tmp0039.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0040 = aarch64_genADD_3(tmp0040, stride, njp1); + tmp0041 = aarch64_genMUL_3(tmp0041, tmp0040, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + tmp0042 = aarch64_genADD_3(tmp0042, In, tmp0041); + if (!tmp0042.dontFree) h2_freeReg(tmp0041.regNro); + tmp0043 = aarch64_genR_3(tmp0043, tmp0042, immValueZero); + tmp0044 = aarch64_genMUL_3(tmp0044, tmp0043, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+2]))}); + if (!tmp0044.dontFree) h2_freeReg(tmp0043.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0044); + if (!sum.dontFree) h2_freeReg(tmp0044.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0045 = aarch64_genDIV_3(tmp0045, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0045, immValueZero); + if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +pifc genKernel5x5(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 41 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 2, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t njm2 = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 13, true}; + h2_sValue_t njp2 = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0084 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0085 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0086 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0087 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0088 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0089 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0090 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0091 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0092 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0093 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0094 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0095 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0096 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0097 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0098 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0099 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0100 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0101 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0102 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0103 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0104 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0105 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0106 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0107 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0108 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0109 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0110 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0111 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0112 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0113 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0114 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0115 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0116 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0117 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0118 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0119 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0120 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0121 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0122 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0123 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0124 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0125 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0126 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFFFF0F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + njm2 = aarch64_genSUB_3(njm2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njm1 = aarch64_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njp1 = aarch64_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njp2 = aarch64_genADD_3(njp2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = aarch64_genADD_3(tmp0000, stride, njm2); + tmp0001 = aarch64_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = aarch64_genADD_3(tmp0002, In, tmp0001); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = aarch64_genR_3(tmp0003, tmp0002, immValueZero); + sum = aarch64_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+0]))}); + if (!sum.dontFree) h2_freeReg(tmp0003.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0004 = aarch64_genADD_3(tmp0004, stride, njm1); + tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = aarch64_genADD_3(tmp0006, In, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = aarch64_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = aarch64_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+1]))}); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0008); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0009 = aarch64_genADD_3(tmp0009, stride, column); + tmp0010 = aarch64_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = aarch64_genADD_3(tmp0011, In, tmp0010); + if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); + tmp0012 = aarch64_genR_3(tmp0012, tmp0011, immValueZero); + tmp0013 = aarch64_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+2]))}); + if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0013); + if (!sum.dontFree) h2_freeReg(tmp0013.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0014 = aarch64_genADD_3(tmp0014, stride, njp1); + tmp0015 = aarch64_genMUL_3(tmp0015, tmp0014, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); + tmp0016 = aarch64_genADD_3(tmp0016, In, tmp0015); + if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); + tmp0017 = aarch64_genR_3(tmp0017, tmp0016, immValueZero); + tmp0018 = aarch64_genMUL_3(tmp0018, tmp0017, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+3]))}); + if (!tmp0018.dontFree) h2_freeReg(tmp0017.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0018); + if (!sum.dontFree) h2_freeReg(tmp0018.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0019 = aarch64_genADD_3(tmp0019, stride, njp2); + tmp0020 = aarch64_genMUL_3(tmp0020, tmp0019, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); + tmp0021 = aarch64_genADD_3(tmp0021, In, tmp0020); + if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); + tmp0022 = aarch64_genR_3(tmp0022, tmp0021, immValueZero); + tmp0023 = aarch64_genMUL_3(tmp0023, tmp0022, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+4]))}); + if (!tmp0023.dontFree) h2_freeReg(tmp0022.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0023); + if (!sum.dontFree) h2_freeReg(tmp0023.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0024 = aarch64_genADD_3(tmp0024, stride, njm2); + tmp0025 = aarch64_genMUL_3(tmp0025, tmp0024, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0025.dontFree) h2_freeReg(tmp0024.regNro); + tmp0026 = aarch64_genADD_3(tmp0026, In, tmp0025); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = aarch64_genR_3(tmp0027, tmp0026, immValueZero); + tmp0028 = aarch64_genMUL_3(tmp0028, tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+0]))}); + if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0028); + if (!sum.dontFree) h2_freeReg(tmp0028.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0029 = aarch64_genADD_3(tmp0029, stride, njm1); + tmp0030 = aarch64_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); + tmp0031 = aarch64_genADD_3(tmp0031, In, tmp0030); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = aarch64_genR_3(tmp0032, tmp0031, immValueZero); + tmp0033 = aarch64_genMUL_3(tmp0033, tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+1]))}); + if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0033); + if (!sum.dontFree) h2_freeReg(tmp0033.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0034 = aarch64_genADD_3(tmp0034, stride, column); + tmp0035 = aarch64_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); + tmp0036 = aarch64_genADD_3(tmp0036, In, tmp0035); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = aarch64_genR_3(tmp0037, tmp0036, immValueZero); + tmp0038 = aarch64_genMUL_3(tmp0038, tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+2]))}); + if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0038); + if (!sum.dontFree) h2_freeReg(tmp0038.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0039 = aarch64_genADD_3(tmp0039, stride, njp1); + tmp0040 = aarch64_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); + tmp0041 = aarch64_genADD_3(tmp0041, In, tmp0040); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + tmp0042 = aarch64_genR_3(tmp0042, tmp0041, immValueZero); + tmp0043 = aarch64_genMUL_3(tmp0043, tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+3]))}); + if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0043); + if (!sum.dontFree) h2_freeReg(tmp0043.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0044 = aarch64_genADD_3(tmp0044, stride, njp2); + tmp0045 = aarch64_genMUL_3(tmp0045, tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); + tmp0046 = aarch64_genADD_3(tmp0046, In, tmp0045); + if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); + tmp0047 = aarch64_genR_3(tmp0047, tmp0046, immValueZero); + tmp0048 = aarch64_genMUL_3(tmp0048, tmp0047, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+4]))}); + if (!tmp0048.dontFree) h2_freeReg(tmp0047.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0048); + if (!sum.dontFree) h2_freeReg(tmp0048.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genMV_3(ni, line, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0050 = aarch64_genADD_3(tmp0050, stride, njm2); + tmp0051 = aarch64_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); + tmp0052 = aarch64_genADD_3(tmp0052, In, tmp0051); + if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); + tmp0053 = aarch64_genR_3(tmp0053, tmp0052, immValueZero); + tmp0054 = aarch64_genMUL_3(tmp0054, tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+0]))}); + if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0054); + if (!sum.dontFree) h2_freeReg(tmp0054.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0055 = aarch64_genADD_3(tmp0055, stride, njm1); + tmp0056 = aarch64_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); + tmp0057 = aarch64_genADD_3(tmp0057, In, tmp0056); + if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); + tmp0058 = aarch64_genR_3(tmp0058, tmp0057, immValueZero); + tmp0059 = aarch64_genMUL_3(tmp0059, tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+1]))}); + if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0059); + if (!sum.dontFree) h2_freeReg(tmp0059.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0060 = aarch64_genADD_3(tmp0060, stride, column); + tmp0061 = aarch64_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); + tmp0062 = aarch64_genADD_3(tmp0062, In, tmp0061); + if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); + tmp0063 = aarch64_genR_3(tmp0063, tmp0062, immValueZero); + tmp0064 = aarch64_genMUL_3(tmp0064, tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+2]))}); + if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0064); + if (!sum.dontFree) h2_freeReg(tmp0064.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0065 = aarch64_genADD_3(tmp0065, stride, njp1); + tmp0066 = aarch64_genMUL_3(tmp0066, tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); + tmp0067 = aarch64_genADD_3(tmp0067, In, tmp0066); + if (!tmp0067.dontFree) h2_freeReg(tmp0066.regNro); + tmp0068 = aarch64_genR_3(tmp0068, tmp0067, immValueZero); + tmp0069 = aarch64_genMUL_3(tmp0069, tmp0068, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+3]))}); + if (!tmp0069.dontFree) h2_freeReg(tmp0068.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0069); + if (!sum.dontFree) h2_freeReg(tmp0069.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0070 = aarch64_genADD_3(tmp0070, stride, njp2); + tmp0071 = aarch64_genMUL_3(tmp0071, tmp0070, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0071.dontFree) h2_freeReg(tmp0070.regNro); + tmp0072 = aarch64_genADD_3(tmp0072, In, tmp0071); + if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); + tmp0073 = aarch64_genR_3(tmp0073, tmp0072, immValueZero); + tmp0074 = aarch64_genMUL_3(tmp0074, tmp0073, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+4]))}); + if (!tmp0074.dontFree) h2_freeReg(tmp0073.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0074); + if (!sum.dontFree) h2_freeReg(tmp0074.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0075 = aarch64_genADD_3(tmp0075, stride, njm2); + tmp0076 = aarch64_genMUL_3(tmp0076, tmp0075, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0076.dontFree) h2_freeReg(tmp0075.regNro); + tmp0077 = aarch64_genADD_3(tmp0077, In, tmp0076); + if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); + tmp0078 = aarch64_genR_3(tmp0078, tmp0077, immValueZero); + tmp0079 = aarch64_genMUL_3(tmp0079, tmp0078, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+0]))}); + if (!tmp0079.dontFree) h2_freeReg(tmp0078.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0079); + if (!sum.dontFree) h2_freeReg(tmp0079.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0080 = aarch64_genADD_3(tmp0080, stride, njm1); + tmp0081 = aarch64_genMUL_3(tmp0081, tmp0080, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0081.dontFree) h2_freeReg(tmp0080.regNro); + tmp0082 = aarch64_genADD_3(tmp0082, In, tmp0081); + if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); + tmp0083 = aarch64_genR_3(tmp0083, tmp0082, immValueZero); + tmp0084 = aarch64_genMUL_3(tmp0084, tmp0083, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+1]))}); + if (!tmp0084.dontFree) h2_freeReg(tmp0083.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0084); + if (!sum.dontFree) h2_freeReg(tmp0084.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0085 = aarch64_genADD_3(tmp0085, stride, column); + tmp0086 = aarch64_genMUL_3(tmp0086, tmp0085, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0086.dontFree) h2_freeReg(tmp0085.regNro); + tmp0087 = aarch64_genADD_3(tmp0087, In, tmp0086); + if (!tmp0087.dontFree) h2_freeReg(tmp0086.regNro); + tmp0088 = aarch64_genR_3(tmp0088, tmp0087, immValueZero); + tmp0089 = aarch64_genMUL_3(tmp0089, tmp0088, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+2]))}); + if (!tmp0089.dontFree) h2_freeReg(tmp0088.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0089); + if (!sum.dontFree) h2_freeReg(tmp0089.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0090 = aarch64_genADD_3(tmp0090, stride, njp1); + tmp0091 = aarch64_genMUL_3(tmp0091, tmp0090, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0091.dontFree) h2_freeReg(tmp0090.regNro); + tmp0092 = aarch64_genADD_3(tmp0092, In, tmp0091); + if (!tmp0092.dontFree) h2_freeReg(tmp0091.regNro); + tmp0093 = aarch64_genR_3(tmp0093, tmp0092, immValueZero); + tmp0094 = aarch64_genMUL_3(tmp0094, tmp0093, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+3]))}); + if (!tmp0094.dontFree) h2_freeReg(tmp0093.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0094); + if (!sum.dontFree) h2_freeReg(tmp0094.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0095 = aarch64_genADD_3(tmp0095, stride, njp2); + tmp0096 = aarch64_genMUL_3(tmp0096, tmp0095, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0096.dontFree) h2_freeReg(tmp0095.regNro); + tmp0097 = aarch64_genADD_3(tmp0097, In, tmp0096); + if (!tmp0097.dontFree) h2_freeReg(tmp0096.regNro); + tmp0098 = aarch64_genR_3(tmp0098, tmp0097, immValueZero); + tmp0099 = aarch64_genMUL_3(tmp0099, tmp0098, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+4]))}); + if (!tmp0099.dontFree) h2_freeReg(tmp0098.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0099); + if (!sum.dontFree) h2_freeReg(tmp0099.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = aarch64_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = aarch64_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0100 = aarch64_genADD_3(tmp0100, stride, njm2); + tmp0101 = aarch64_genMUL_3(tmp0101, tmp0100, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0101.dontFree) h2_freeReg(tmp0100.regNro); + tmp0102 = aarch64_genADD_3(tmp0102, In, tmp0101); + if (!tmp0102.dontFree) h2_freeReg(tmp0101.regNro); + tmp0103 = aarch64_genR_3(tmp0103, tmp0102, immValueZero); + tmp0104 = aarch64_genMUL_3(tmp0104, tmp0103, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+0]))}); + if (!tmp0104.dontFree) h2_freeReg(tmp0103.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0104); + if (!sum.dontFree) h2_freeReg(tmp0104.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0105 = aarch64_genADD_3(tmp0105, stride, njm1); + tmp0106 = aarch64_genMUL_3(tmp0106, tmp0105, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0106.dontFree) h2_freeReg(tmp0105.regNro); + tmp0107 = aarch64_genADD_3(tmp0107, In, tmp0106); + if (!tmp0107.dontFree) h2_freeReg(tmp0106.regNro); + tmp0108 = aarch64_genR_3(tmp0108, tmp0107, immValueZero); + tmp0109 = aarch64_genMUL_3(tmp0109, tmp0108, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+1]))}); + if (!tmp0109.dontFree) h2_freeReg(tmp0108.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0109); + if (!sum.dontFree) h2_freeReg(tmp0109.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0110 = aarch64_genADD_3(tmp0110, stride, column); + tmp0111 = aarch64_genMUL_3(tmp0111, tmp0110, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0111.dontFree) h2_freeReg(tmp0110.regNro); + tmp0112 = aarch64_genADD_3(tmp0112, In, tmp0111); + if (!tmp0112.dontFree) h2_freeReg(tmp0111.regNro); + tmp0113 = aarch64_genR_3(tmp0113, tmp0112, immValueZero); + tmp0114 = aarch64_genMUL_3(tmp0114, tmp0113, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+2]))}); + if (!tmp0114.dontFree) h2_freeReg(tmp0113.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0114); + if (!sum.dontFree) h2_freeReg(tmp0114.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0115 = aarch64_genADD_3(tmp0115, stride, njp1); + tmp0116 = aarch64_genMUL_3(tmp0116, tmp0115, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0116.dontFree) h2_freeReg(tmp0115.regNro); + tmp0117 = aarch64_genADD_3(tmp0117, In, tmp0116); + if (!tmp0117.dontFree) h2_freeReg(tmp0116.regNro); + tmp0118 = aarch64_genR_3(tmp0118, tmp0117, immValueZero); + tmp0119 = aarch64_genMUL_3(tmp0119, tmp0118, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+3]))}); + if (!tmp0119.dontFree) h2_freeReg(tmp0118.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0119); + if (!sum.dontFree) h2_freeReg(tmp0119.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0120 = aarch64_genADD_3(tmp0120, stride, njp2); + tmp0121 = aarch64_genMUL_3(tmp0121, tmp0120, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0121.dontFree) h2_freeReg(tmp0120.regNro); + tmp0122 = aarch64_genADD_3(tmp0122, In, tmp0121); + if (!tmp0122.dontFree) h2_freeReg(tmp0121.regNro); + tmp0123 = aarch64_genR_3(tmp0123, tmp0122, immValueZero); + tmp0124 = aarch64_genMUL_3(tmp0124, tmp0123, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+4]))}); + if (!tmp0124.dontFree) h2_freeReg(tmp0123.regNro); + sum = aarch64_genADD_3(sum, sum, tmp0124); + if (!sum.dontFree) h2_freeReg(tmp0124.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0125 = aarch64_genDIV_3(tmp0125, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0125, immValueZero); + if (!tmp0126.dontFree) h2_freeReg(tmp0125.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +#if 0 +#endif +} + +// Compute a stencil for 1 point +int kernelStatic(imgStruct_t *In, int l, int c, imgStruct_t *Filter, int coeff) +{ + int line, column, sum = 0; + int offset = (Filter->width)/2; + + for (line = 0; line < Filter->height; line++) + { + for (column = 0; column < Filter->width; column++) + { + int ni = (l + line) - offset; + int nj = (c + column) - offset; + sum += In->pixelsArray[ni*In->width+nj] * Filter->pixelsArray[line*Filter->width+column]; + } + } + return sum / coeff; +} + + +void convolutionStatic(imgStruct_t *In, imgStruct_t *Out, imgStruct_t *Filter, int coeff) +{ + int offset = Filter->width/2; + int result; + for (int line = offset; line < In->height - offset; line++) + { + for (int column = offset; column < In->width - offset; column++) + { + result = kernelStatic(In, line, column, Filter, coeff); + Out->pixelsArray[line*Out->width+column] = clamp(result); + } + } +} + +void convolutionH4(imgStruct_t* In, imgStruct_t *Out, imgStruct_t *Filter, pifc kernelHL) +{ + int offset = Filter->width/2; + int result; + for (int line = offset; line < In->height - offset; line++) + { + for (int column = offset; column < In->width - offset; column++) + { + result = kernelHL(In->pixelsArray, line, column, In->width); + Out->pixelsArray[line*Out->width+column] = clamp(result); + } + } +} + +int compareImages(imgStruct_t *staticImg, imgStruct_t *H4Img) +{ + int errors = 0; + for(int line = 0 ; line < staticImg->height ; line++) + { + for(int column = 0 ; column < staticImg->width ; column++) + { + if((staticImg->pixelsArray[line*staticImg->width+column] - H4Img->pixelsArray[line*H4Img->width+column]) != 0) + { + if (0 == errors) + { + printf("Alert : first difference at line %i column %i\n", line, column); + } + errors++; + } + } + } + return errors; +} + +int main(int argc, char *argv[]) +{ + int error, coeff, nXperiment = 20; + imgStruct_t *In, *OutH4, *OutStatic, *Filter; + char *filterImageName, *inputImageName; + if (argc < 5) + { + printf ("./Stencil \n"); + exit(-1); + } + + inputImageName = argv[1]; + filterImageName = argv[4]; + In = readPgmImage(inputImageName); + Filter = readPgmImage(filterImageName); + coeff = imgSum (Filter); +#ifdef VERBOSE + printf ("%s: coeff %d\n", filterImageName, coeff); + printImage (Filter, "Filter"); +#endif + assert (Filter->width == Filter->height); // Only square filters + OutStatic = createImage (In->height, In->width); + OutH4 = createImage (In->height, In->width); +#ifdef VERBOSE + printf ("after init\n"); + printImage(In, "In"); +#endif + ticks_t timeStatic = h2_getticks(); // Static convolution + for (int i = 0; i < nXperiment; i++) + { + convolutionStatic(In, OutStatic, Filter, coeff); + } + timeStatic = h2_getticks() - timeStatic; +#ifdef VERBOSE + printf ("after static\n"); + printImage(OutStatic, "Out"); +#endif + + pifc kernelHL = (pifc)h2_malloc(8192); + ticks_t timeCodeGen = h2_getticks(); + switch (Filter->width) + { + case 1 : kernelHL = genKernel1x1 (kernelHL, Filter->pixelsArray, coeff); break; + case 3 : kernelHL = genKernel3x3 (kernelHL, Filter->pixelsArray, coeff); break; + case 5 : kernelHL = genKernel5x5 (kernelHL, Filter->pixelsArray, coeff); break; + default: printf ("Unknown filter size\n"); exit(-1); + } + timeCodeGen = h2_getticks() - timeCodeGen; + +#ifdef VERBOSE + printf ("after codegen\n"); +#endif + + ticks_t timeH4 = h2_getticks(); // Compilette convolution + for (int i = 0; i < nXperiment; i++) + { + convolutionH4(In, OutH4, Filter, kernelHL); + } + timeH4 = h2_getticks() - timeH4; +#ifdef VERBOSE + printf ("after h2\n"); + printImage(OutH4, "Out H4"); +#endif + error = compareImages(OutH4, OutStatic); + printf("%s;%ix%i;%ix%i;%lld;%lld;%lld;%d;%d\n", + filterImageName, + Filter->width, Filter->height, In->width, In->height, + timeStatic/nXperiment, timeH4/nXperiment, + h2_codeGenTime, h2_insnGenerated, + error); + +#if VERBOSE + writePgmImage(OutStatic, argv[2]); + writePgmImage(OutH4, argv[3]); +#endif + + return (0 == error)?0:-1; +} diff --git a/Demos/Stencil/Stencil.power b/Demos/Stencil/Stencil.power new file mode 100755 index 0000000000000000000000000000000000000000..1df4537a7f78e0c90c5bc7ea09c62dc81790da3e GIT binary patch literal 145696 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 literal 0 HcmV?d00001 diff --git a/Demos/Stencil/Stencil.power.c b/Demos/Stencil/Stencil.power.c new file mode 100644 index 0000000..826cc9f --- /dev/null +++ b/Demos/Stencil/Stencil.power.c @@ -0,0 +1,1955 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); +#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (power)\\n"); + #endif + P2 = power_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include +#include +#include +#include "ReadPgmImage.h" + +typedef int (*pifc)(int[], int, int, int); + + +void printImage(imgStruct_t *img, char *imageName) +{ + printf ("ImageName & size: %s %dx%d\n", imageName, img->height, img->width); + for(int line = 0 ; line < img->height ; line++) + { + for(int column = 0 ; column < img->width ; column++) + { + printf("%03d ", img->pixelsArray[line*img->width+column]); + } + printf("\n"); + } + printf("\n"); +} + +int imgSum (imgStruct_t *img) +{ + int line, column, sum; + sum = 0; + for(int line = 0 ; line < img->height ; line++) + { + for(int column = 0 ; column < img->width; column++) + { + sum += img->pixelsArray[line*img->width+column]; + } + } + return (0 == sum)?1:sum; +} + +#if 0 +unsigned char clamp(int value) +{ + return (unsigned char)(0 > value)?0:(255 < value)?255:value; +} +#else +#define clamp(value) ((unsigned char)(0 > value)?0:(255 < value)?255:value) +#endif + +pifc genKernel1x1(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x787F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, line, imgWidth); + tmp0001 = power_genADD_3(tmp0001, tmp0000, column); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = power_genMUL_3(tmp0002, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = power_genADD_3(tmp0003, In, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = power_genR_3(tmp0004, tmp0003, immValueZero); + sum = power_genMUL_3(sum, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); + if (!sum.dontFree) h2_freeReg(tmp0004.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0005 = power_genDIV_3(tmp0005, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +pifc genKernel3x3(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 19 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 17, true}; + h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 18, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7F87F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + njp1 = power_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njm1 = power_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = power_genADD_3(tmp0000, stride, njm1); + tmp0001 = power_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = power_genADD_3(tmp0002, In, tmp0001); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = power_genR_3(tmp0003, tmp0002, immValueZero); + sum = power_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); + if (!sum.dontFree) h2_freeReg(tmp0003.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0004 = power_genADD_3(tmp0004, stride, column); + tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = power_genADD_3(tmp0006, In, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = power_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = power_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1]))}); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = power_genADD_3(sum, sum, tmp0008); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0009 = power_genADD_3(tmp0009, stride, njp1); + tmp0010 = power_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = power_genADD_3(tmp0011, In, tmp0010); + if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); + tmp0012 = power_genR_3(tmp0012, tmp0011, immValueZero); + tmp0013 = power_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2]))}); + if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); + sum = power_genADD_3(sum, sum, tmp0013); + if (!sum.dontFree) h2_freeReg(tmp0013.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genMV_2(ni, line); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0015 = power_genADD_3(tmp0015, stride, njm1); + tmp0016 = power_genMUL_3(tmp0016, tmp0015, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); + tmp0017 = power_genADD_3(tmp0017, In, tmp0016); + if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); + tmp0018 = power_genR_3(tmp0018, tmp0017, immValueZero); + tmp0019 = power_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+0]))}); + if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); + sum = power_genADD_3(sum, sum, tmp0019); + if (!sum.dontFree) h2_freeReg(tmp0019.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0020 = power_genADD_3(tmp0020, stride, column); + tmp0021 = power_genMUL_3(tmp0021, tmp0020, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); + tmp0022 = power_genADD_3(tmp0022, In, tmp0021); + if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); + tmp0023 = power_genR_3(tmp0023, tmp0022, immValueZero); + tmp0024 = power_genMUL_3(tmp0024, tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+1]))}); + if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); + sum = power_genADD_3(sum, sum, tmp0024); + if (!sum.dontFree) h2_freeReg(tmp0024.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0025 = power_genADD_3(tmp0025, stride, njp1); + tmp0026 = power_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = power_genADD_3(tmp0027, In, tmp0026); + if (!tmp0027.dontFree) h2_freeReg(tmp0026.regNro); + tmp0028 = power_genR_3(tmp0028, tmp0027, immValueZero); + tmp0029 = power_genMUL_3(tmp0029, tmp0028, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+2]))}); + if (!tmp0029.dontFree) h2_freeReg(tmp0028.regNro); + sum = power_genADD_3(sum, sum, tmp0029); + if (!sum.dontFree) h2_freeReg(tmp0029.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0030 = power_genADD_3(tmp0030, stride, njm1); + tmp0031 = power_genMUL_3(tmp0031, tmp0030, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = power_genADD_3(tmp0032, In, tmp0031); + if (!tmp0032.dontFree) h2_freeReg(tmp0031.regNro); + tmp0033 = power_genR_3(tmp0033, tmp0032, immValueZero); + tmp0034 = power_genMUL_3(tmp0034, tmp0033, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+0]))}); + if (!tmp0034.dontFree) h2_freeReg(tmp0033.regNro); + sum = power_genADD_3(sum, sum, tmp0034); + if (!sum.dontFree) h2_freeReg(tmp0034.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0035 = power_genADD_3(tmp0035, stride, column); + tmp0036 = power_genMUL_3(tmp0036, tmp0035, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = power_genADD_3(tmp0037, In, tmp0036); + if (!tmp0037.dontFree) h2_freeReg(tmp0036.regNro); + tmp0038 = power_genR_3(tmp0038, tmp0037, immValueZero); + tmp0039 = power_genMUL_3(tmp0039, tmp0038, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+1]))}); + if (!tmp0039.dontFree) h2_freeReg(tmp0038.regNro); + sum = power_genADD_3(sum, sum, tmp0039); + if (!sum.dontFree) h2_freeReg(tmp0039.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0040 = power_genADD_3(tmp0040, stride, njp1); + tmp0041 = power_genMUL_3(tmp0041, tmp0040, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + tmp0042 = power_genADD_3(tmp0042, In, tmp0041); + if (!tmp0042.dontFree) h2_freeReg(tmp0041.regNro); + tmp0043 = power_genR_3(tmp0043, tmp0042, immValueZero); + tmp0044 = power_genMUL_3(tmp0044, tmp0043, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+2]))}); + if (!tmp0044.dontFree) h2_freeReg(tmp0043.regNro); + sum = power_genADD_3(sum, sum, tmp0044); + if (!sum.dontFree) h2_freeReg(tmp0044.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0045 = power_genDIV_3(tmp0045, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0045); + if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +pifc genKernel5x5(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 41 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t njm2 = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 17, true}; + h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 18, true}; + h2_sValue_t njp2 = {H2REGISTER, 'i', 1, 32, 19, true}; + h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 20, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0084 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0085 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0086 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0087 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0088 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0089 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0090 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0091 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0092 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0093 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0094 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0095 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0096 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0097 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0098 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0099 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0100 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0101 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0102 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0103 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0104 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0105 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0106 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0107 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0108 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0109 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0110 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0111 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0112 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0113 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0114 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0115 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0116 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0117 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0118 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0119 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0120 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0121 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0122 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0123 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0124 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0125 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0126 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1FF87F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + njm2 = power_genSUB_3(njm2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njm1 = power_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njp1 = power_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njp2 = power_genADD_3(njp2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = power_genADD_3(tmp0000, stride, njm2); + tmp0001 = power_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = power_genADD_3(tmp0002, In, tmp0001); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = power_genR_3(tmp0003, tmp0002, immValueZero); + sum = power_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+0]))}); + if (!sum.dontFree) h2_freeReg(tmp0003.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0004 = power_genADD_3(tmp0004, stride, njm1); + tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = power_genADD_3(tmp0006, In, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = power_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = power_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+1]))}); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = power_genADD_3(sum, sum, tmp0008); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0009 = power_genADD_3(tmp0009, stride, column); + tmp0010 = power_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = power_genADD_3(tmp0011, In, tmp0010); + if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); + tmp0012 = power_genR_3(tmp0012, tmp0011, immValueZero); + tmp0013 = power_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+2]))}); + if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); + sum = power_genADD_3(sum, sum, tmp0013); + if (!sum.dontFree) h2_freeReg(tmp0013.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0014 = power_genADD_3(tmp0014, stride, njp1); + tmp0015 = power_genMUL_3(tmp0015, tmp0014, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); + tmp0016 = power_genADD_3(tmp0016, In, tmp0015); + if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); + tmp0017 = power_genR_3(tmp0017, tmp0016, immValueZero); + tmp0018 = power_genMUL_3(tmp0018, tmp0017, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+3]))}); + if (!tmp0018.dontFree) h2_freeReg(tmp0017.regNro); + sum = power_genADD_3(sum, sum, tmp0018); + if (!sum.dontFree) h2_freeReg(tmp0018.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0019 = power_genADD_3(tmp0019, stride, njp2); + tmp0020 = power_genMUL_3(tmp0020, tmp0019, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); + tmp0021 = power_genADD_3(tmp0021, In, tmp0020); + if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); + tmp0022 = power_genR_3(tmp0022, tmp0021, immValueZero); + tmp0023 = power_genMUL_3(tmp0023, tmp0022, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+4]))}); + if (!tmp0023.dontFree) h2_freeReg(tmp0022.regNro); + sum = power_genADD_3(sum, sum, tmp0023); + if (!sum.dontFree) h2_freeReg(tmp0023.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0024 = power_genADD_3(tmp0024, stride, njm2); + tmp0025 = power_genMUL_3(tmp0025, tmp0024, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0025.dontFree) h2_freeReg(tmp0024.regNro); + tmp0026 = power_genADD_3(tmp0026, In, tmp0025); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = power_genR_3(tmp0027, tmp0026, immValueZero); + tmp0028 = power_genMUL_3(tmp0028, tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+0]))}); + if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); + sum = power_genADD_3(sum, sum, tmp0028); + if (!sum.dontFree) h2_freeReg(tmp0028.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0029 = power_genADD_3(tmp0029, stride, njm1); + tmp0030 = power_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); + tmp0031 = power_genADD_3(tmp0031, In, tmp0030); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = power_genR_3(tmp0032, tmp0031, immValueZero); + tmp0033 = power_genMUL_3(tmp0033, tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+1]))}); + if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); + sum = power_genADD_3(sum, sum, tmp0033); + if (!sum.dontFree) h2_freeReg(tmp0033.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0034 = power_genADD_3(tmp0034, stride, column); + tmp0035 = power_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); + tmp0036 = power_genADD_3(tmp0036, In, tmp0035); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = power_genR_3(tmp0037, tmp0036, immValueZero); + tmp0038 = power_genMUL_3(tmp0038, tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+2]))}); + if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); + sum = power_genADD_3(sum, sum, tmp0038); + if (!sum.dontFree) h2_freeReg(tmp0038.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0039 = power_genADD_3(tmp0039, stride, njp1); + tmp0040 = power_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); + tmp0041 = power_genADD_3(tmp0041, In, tmp0040); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + tmp0042 = power_genR_3(tmp0042, tmp0041, immValueZero); + tmp0043 = power_genMUL_3(tmp0043, tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+3]))}); + if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); + sum = power_genADD_3(sum, sum, tmp0043); + if (!sum.dontFree) h2_freeReg(tmp0043.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0044 = power_genADD_3(tmp0044, stride, njp2); + tmp0045 = power_genMUL_3(tmp0045, tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); + tmp0046 = power_genADD_3(tmp0046, In, tmp0045); + if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); + tmp0047 = power_genR_3(tmp0047, tmp0046, immValueZero); + tmp0048 = power_genMUL_3(tmp0048, tmp0047, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+4]))}); + if (!tmp0048.dontFree) h2_freeReg(tmp0047.regNro); + sum = power_genADD_3(sum, sum, tmp0048); + if (!sum.dontFree) h2_freeReg(tmp0048.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genMV_2(ni, line); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0050 = power_genADD_3(tmp0050, stride, njm2); + tmp0051 = power_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); + tmp0052 = power_genADD_3(tmp0052, In, tmp0051); + if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); + tmp0053 = power_genR_3(tmp0053, tmp0052, immValueZero); + tmp0054 = power_genMUL_3(tmp0054, tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+0]))}); + if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); + sum = power_genADD_3(sum, sum, tmp0054); + if (!sum.dontFree) h2_freeReg(tmp0054.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0055 = power_genADD_3(tmp0055, stride, njm1); + tmp0056 = power_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); + tmp0057 = power_genADD_3(tmp0057, In, tmp0056); + if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); + tmp0058 = power_genR_3(tmp0058, tmp0057, immValueZero); + tmp0059 = power_genMUL_3(tmp0059, tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+1]))}); + if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); + sum = power_genADD_3(sum, sum, tmp0059); + if (!sum.dontFree) h2_freeReg(tmp0059.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0060 = power_genADD_3(tmp0060, stride, column); + tmp0061 = power_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); + tmp0062 = power_genADD_3(tmp0062, In, tmp0061); + if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); + tmp0063 = power_genR_3(tmp0063, tmp0062, immValueZero); + tmp0064 = power_genMUL_3(tmp0064, tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+2]))}); + if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); + sum = power_genADD_3(sum, sum, tmp0064); + if (!sum.dontFree) h2_freeReg(tmp0064.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0065 = power_genADD_3(tmp0065, stride, njp1); + tmp0066 = power_genMUL_3(tmp0066, tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); + tmp0067 = power_genADD_3(tmp0067, In, tmp0066); + if (!tmp0067.dontFree) h2_freeReg(tmp0066.regNro); + tmp0068 = power_genR_3(tmp0068, tmp0067, immValueZero); + tmp0069 = power_genMUL_3(tmp0069, tmp0068, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+3]))}); + if (!tmp0069.dontFree) h2_freeReg(tmp0068.regNro); + sum = power_genADD_3(sum, sum, tmp0069); + if (!sum.dontFree) h2_freeReg(tmp0069.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0070 = power_genADD_3(tmp0070, stride, njp2); + tmp0071 = power_genMUL_3(tmp0071, tmp0070, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0071.dontFree) h2_freeReg(tmp0070.regNro); + tmp0072 = power_genADD_3(tmp0072, In, tmp0071); + if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); + tmp0073 = power_genR_3(tmp0073, tmp0072, immValueZero); + tmp0074 = power_genMUL_3(tmp0074, tmp0073, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+4]))}); + if (!tmp0074.dontFree) h2_freeReg(tmp0073.regNro); + sum = power_genADD_3(sum, sum, tmp0074); + if (!sum.dontFree) h2_freeReg(tmp0074.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0075 = power_genADD_3(tmp0075, stride, njm2); + tmp0076 = power_genMUL_3(tmp0076, tmp0075, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0076.dontFree) h2_freeReg(tmp0075.regNro); + tmp0077 = power_genADD_3(tmp0077, In, tmp0076); + if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); + tmp0078 = power_genR_3(tmp0078, tmp0077, immValueZero); + tmp0079 = power_genMUL_3(tmp0079, tmp0078, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+0]))}); + if (!tmp0079.dontFree) h2_freeReg(tmp0078.regNro); + sum = power_genADD_3(sum, sum, tmp0079); + if (!sum.dontFree) h2_freeReg(tmp0079.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0080 = power_genADD_3(tmp0080, stride, njm1); + tmp0081 = power_genMUL_3(tmp0081, tmp0080, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0081.dontFree) h2_freeReg(tmp0080.regNro); + tmp0082 = power_genADD_3(tmp0082, In, tmp0081); + if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); + tmp0083 = power_genR_3(tmp0083, tmp0082, immValueZero); + tmp0084 = power_genMUL_3(tmp0084, tmp0083, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+1]))}); + if (!tmp0084.dontFree) h2_freeReg(tmp0083.regNro); + sum = power_genADD_3(sum, sum, tmp0084); + if (!sum.dontFree) h2_freeReg(tmp0084.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0085 = power_genADD_3(tmp0085, stride, column); + tmp0086 = power_genMUL_3(tmp0086, tmp0085, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0086.dontFree) h2_freeReg(tmp0085.regNro); + tmp0087 = power_genADD_3(tmp0087, In, tmp0086); + if (!tmp0087.dontFree) h2_freeReg(tmp0086.regNro); + tmp0088 = power_genR_3(tmp0088, tmp0087, immValueZero); + tmp0089 = power_genMUL_3(tmp0089, tmp0088, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+2]))}); + if (!tmp0089.dontFree) h2_freeReg(tmp0088.regNro); + sum = power_genADD_3(sum, sum, tmp0089); + if (!sum.dontFree) h2_freeReg(tmp0089.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0090 = power_genADD_3(tmp0090, stride, njp1); + tmp0091 = power_genMUL_3(tmp0091, tmp0090, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0091.dontFree) h2_freeReg(tmp0090.regNro); + tmp0092 = power_genADD_3(tmp0092, In, tmp0091); + if (!tmp0092.dontFree) h2_freeReg(tmp0091.regNro); + tmp0093 = power_genR_3(tmp0093, tmp0092, immValueZero); + tmp0094 = power_genMUL_3(tmp0094, tmp0093, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+3]))}); + if (!tmp0094.dontFree) h2_freeReg(tmp0093.regNro); + sum = power_genADD_3(sum, sum, tmp0094); + if (!sum.dontFree) h2_freeReg(tmp0094.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0095 = power_genADD_3(tmp0095, stride, njp2); + tmp0096 = power_genMUL_3(tmp0096, tmp0095, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0096.dontFree) h2_freeReg(tmp0095.regNro); + tmp0097 = power_genADD_3(tmp0097, In, tmp0096); + if (!tmp0097.dontFree) h2_freeReg(tmp0096.regNro); + tmp0098 = power_genR_3(tmp0098, tmp0097, immValueZero); + tmp0099 = power_genMUL_3(tmp0099, tmp0098, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+4]))}); + if (!tmp0099.dontFree) h2_freeReg(tmp0098.regNro); + sum = power_genADD_3(sum, sum, tmp0099); + if (!sum.dontFree) h2_freeReg(tmp0099.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = power_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = power_genMUL_3(stride, ni, imgWidth); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0100 = power_genADD_3(tmp0100, stride, njm2); + tmp0101 = power_genMUL_3(tmp0101, tmp0100, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0101.dontFree) h2_freeReg(tmp0100.regNro); + tmp0102 = power_genADD_3(tmp0102, In, tmp0101); + if (!tmp0102.dontFree) h2_freeReg(tmp0101.regNro); + tmp0103 = power_genR_3(tmp0103, tmp0102, immValueZero); + tmp0104 = power_genMUL_3(tmp0104, tmp0103, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+0]))}); + if (!tmp0104.dontFree) h2_freeReg(tmp0103.regNro); + sum = power_genADD_3(sum, sum, tmp0104); + if (!sum.dontFree) h2_freeReg(tmp0104.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0105 = power_genADD_3(tmp0105, stride, njm1); + tmp0106 = power_genMUL_3(tmp0106, tmp0105, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0106.dontFree) h2_freeReg(tmp0105.regNro); + tmp0107 = power_genADD_3(tmp0107, In, tmp0106); + if (!tmp0107.dontFree) h2_freeReg(tmp0106.regNro); + tmp0108 = power_genR_3(tmp0108, tmp0107, immValueZero); + tmp0109 = power_genMUL_3(tmp0109, tmp0108, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+1]))}); + if (!tmp0109.dontFree) h2_freeReg(tmp0108.regNro); + sum = power_genADD_3(sum, sum, tmp0109); + if (!sum.dontFree) h2_freeReg(tmp0109.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0110 = power_genADD_3(tmp0110, stride, column); + tmp0111 = power_genMUL_3(tmp0111, tmp0110, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0111.dontFree) h2_freeReg(tmp0110.regNro); + tmp0112 = power_genADD_3(tmp0112, In, tmp0111); + if (!tmp0112.dontFree) h2_freeReg(tmp0111.regNro); + tmp0113 = power_genR_3(tmp0113, tmp0112, immValueZero); + tmp0114 = power_genMUL_3(tmp0114, tmp0113, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+2]))}); + if (!tmp0114.dontFree) h2_freeReg(tmp0113.regNro); + sum = power_genADD_3(sum, sum, tmp0114); + if (!sum.dontFree) h2_freeReg(tmp0114.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0115 = power_genADD_3(tmp0115, stride, njp1); + tmp0116 = power_genMUL_3(tmp0116, tmp0115, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0116.dontFree) h2_freeReg(tmp0115.regNro); + tmp0117 = power_genADD_3(tmp0117, In, tmp0116); + if (!tmp0117.dontFree) h2_freeReg(tmp0116.regNro); + tmp0118 = power_genR_3(tmp0118, tmp0117, immValueZero); + tmp0119 = power_genMUL_3(tmp0119, tmp0118, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+3]))}); + if (!tmp0119.dontFree) h2_freeReg(tmp0118.regNro); + sum = power_genADD_3(sum, sum, tmp0119); + if (!sum.dontFree) h2_freeReg(tmp0119.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0120 = power_genADD_3(tmp0120, stride, njp2); + tmp0121 = power_genMUL_3(tmp0121, tmp0120, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + if (!tmp0121.dontFree) h2_freeReg(tmp0120.regNro); + tmp0122 = power_genADD_3(tmp0122, In, tmp0121); + if (!tmp0122.dontFree) h2_freeReg(tmp0121.regNro); + tmp0123 = power_genR_3(tmp0123, tmp0122, immValueZero); + tmp0124 = power_genMUL_3(tmp0124, tmp0123, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+4]))}); + if (!tmp0124.dontFree) h2_freeReg(tmp0123.regNro); + sum = power_genADD_3(sum, sum, tmp0124); + if (!sum.dontFree) h2_freeReg(tmp0124.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0125 = power_genDIV_3(tmp0125, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); + h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0125); + if (!tmp0126.dontFree) h2_freeReg(tmp0125.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +#if 0 +#endif +} + +// Compute a stencil for 1 point +int kernelStatic(imgStruct_t *In, int l, int c, imgStruct_t *Filter, int coeff) +{ + int line, column, sum = 0; + int offset = (Filter->width)/2; + + for (line = 0; line < Filter->height; line++) + { + for (column = 0; column < Filter->width; column++) + { + int ni = (l + line) - offset; + int nj = (c + column) - offset; + sum += In->pixelsArray[ni*In->width+nj] * Filter->pixelsArray[line*Filter->width+column]; + } + } + return sum / coeff; +} + + +void convolutionStatic(imgStruct_t *In, imgStruct_t *Out, imgStruct_t *Filter, int coeff) +{ + int offset = Filter->width/2; + int result; + for (int line = offset; line < In->height - offset; line++) + { + for (int column = offset; column < In->width - offset; column++) + { + result = kernelStatic(In, line, column, Filter, coeff); + Out->pixelsArray[line*Out->width+column] = clamp(result); + } + } +} + +void convolutionH4(imgStruct_t* In, imgStruct_t *Out, imgStruct_t *Filter, pifc kernelHL) +{ + int offset = Filter->width/2; + int result; + for (int line = offset; line < In->height - offset; line++) + { + for (int column = offset; column < In->width - offset; column++) + { + result = kernelHL(In->pixelsArray, line, column, In->width); + Out->pixelsArray[line*Out->width+column] = clamp(result); + } + } +} + +int compareImages(imgStruct_t *staticImg, imgStruct_t *H4Img) +{ + int errors = 0; + for(int line = 0 ; line < staticImg->height ; line++) + { + for(int column = 0 ; column < staticImg->width ; column++) + { + if((staticImg->pixelsArray[line*staticImg->width+column] - H4Img->pixelsArray[line*H4Img->width+column]) != 0) + { + if (0 == errors) + { + printf("Alert : first difference at line %i column %i\n", line, column); + } + errors++; + } + } + } + return errors; +} + +int main(int argc, char *argv[]) +{ + int error, coeff, nXperiment = 20; + imgStruct_t *In, *OutH4, *OutStatic, *Filter; + char *filterImageName, *inputImageName; + if (argc < 5) + { + printf ("./Stencil \n"); + exit(-1); + } + + inputImageName = argv[1]; + filterImageName = argv[4]; + In = readPgmImage(inputImageName); + Filter = readPgmImage(filterImageName); + coeff = imgSum (Filter); +#ifdef VERBOSE + printf ("%s: coeff %d\n", filterImageName, coeff); + printImage (Filter, "Filter"); +#endif + assert (Filter->width == Filter->height); // Only square filters + OutStatic = createImage (In->height, In->width); + OutH4 = createImage (In->height, In->width); +#ifdef VERBOSE + printf ("after init\n"); + printImage(In, "In"); +#endif + ticks_t timeStatic = h2_getticks(); // Static convolution + for (int i = 0; i < nXperiment; i++) + { + convolutionStatic(In, OutStatic, Filter, coeff); + } + timeStatic = h2_getticks() - timeStatic; +#ifdef VERBOSE + printf ("after static\n"); + printImage(OutStatic, "Out"); +#endif + + pifc kernelHL = (pifc)h2_malloc(8192); + ticks_t timeCodeGen = h2_getticks(); + switch (Filter->width) + { + case 1 : kernelHL = genKernel1x1 (kernelHL, Filter->pixelsArray, coeff); break; + case 3 : kernelHL = genKernel3x3 (kernelHL, Filter->pixelsArray, coeff); break; + case 5 : kernelHL = genKernel5x5 (kernelHL, Filter->pixelsArray, coeff); break; + default: printf ("Unknown filter size\n"); exit(-1); + } + timeCodeGen = h2_getticks() - timeCodeGen; + +#ifdef VERBOSE + printf ("after codegen\n"); +#endif + + ticks_t timeH4 = h2_getticks(); // Compilette convolution + for (int i = 0; i < nXperiment; i++) + { + convolutionH4(In, OutH4, Filter, kernelHL); + } + timeH4 = h2_getticks() - timeH4; +#ifdef VERBOSE + printf ("after h2\n"); + printImage(OutH4, "Out H4"); +#endif + error = compareImages(OutH4, OutStatic); + printf("%s;%ix%i;%ix%i;%lld;%lld;%lld;%d;%d\n", + filterImageName, + Filter->width, Filter->height, In->width, In->height, + timeStatic/nXperiment, timeH4/nXperiment, + h2_codeGenTime, h2_insnGenerated, + error); + +#if VERBOSE + writePgmImage(OutStatic, argv[2]); + writePgmImage(OutH4, argv[3]); +#endif + + return (0 == error)?0:-1; +} diff --git a/Demos/Stencil/Stencil.riscv b/Demos/Stencil/Stencil.riscv new file mode 100755 index 0000000000000000000000000000000000000000..60c93461d991da91012ba0558f9cc14c29dff531 GIT binary patch literal 171700 zcmeFa3wTt;{l~q@S=q>+0*V!Dy{x;*VVkD$T5GM0? z)t0}>b7E{M0A#WAyDS=IH0{yQmBmF{7I}=H)W zV)O$mu8Xy;xK2}L5a-Hb9{(-JIsIFIl0MzrZs&O9_!{|57Kw+9?c!mN-hc712Yxo} z(Z~Nf_Gcp>9W`{!<(K{J(P1MlzwCkJQNxojHO`f^zT z;7_)@Q+_}>ha&$Jzxe-I6e$x)PmZxS<#bBqUsoDGq?{f3BlS3=?co32B98T-{(lke zUJ-RUX89-O5IJ7?yQC*eTAJ%ot-9+Ds`7`c`1cXpZKt16(9@O{)3aZi{8|1Rn9~HU7q{b9`kOw>DH&79o6Hyr>Bog?*HrBbDr*+b=|QOOP3y) zyl(c_kM}75BD>Gwvv(go?40(q{CB3FchQE^kN5mX{coEkS&M)A=O144`Y(SlfAX*X?YMZf?6TG03R)wu8~G>45>J`uXlY+94@4ZlkY;tn z@&2^aBH9P!`Hx7+N!cAbF@*o8MBp!@JtE?K+0*2Rmf8~b}4~`r;e5CEcv5$_n4IX^os8J7& z96k7<`yL%84-b9hzLBhiY*svT?FDG%}&KSZ;gCJm53kE|O`CP~%}gS zTbcJ#sc6yo@?IG$$ERndr^zEzslW8x)K3yp zj*nmVLPo}m@3lVX`ZHWXUwO>LE^8)){&ZbNsypq_#Q7;M@AWb1X)E9Q`xCCswsYLc zMU8IV-gIe!uTQWk!{OFN6SdsNh<#bcTdA6@S4LLp zQ@@I_9ZtF5dm0q~{zR9}u1&^Bk`^|)6N8P%Q{65(4)1ZdQ#5IM@VGC*e>{vXFTMV9 zjx@=U{;XJ|mse94JX{w$p~k4E*2S7VmB0S{uP!YJ;~Zr#g9|b~V~$NbH#!=Ba?|Ny zYVo4!2L&4A4^wNQaQd&pvvPBWtnJ(;QHL(|C3u^(1bfr*pa0~hr+yh@n?KN{I26HG zV>WKjrpBpR z{X=Tb>dMvA%GFs)il#K=dHFZWdAZ~5O+PP|^UQcQW2gK*??yT5jJ^wI)Y|?uN&T`~ z{&HIQtgJ9MIKv@lsBz?Y>du3q#xU1X%YN`ncWzAf@jI{0XpxwyIZ%66(hnYAaA#dg z#M7ssjH0qxE#sV8Osb^{ibG_ zXDo2krS$rwkIh~5dCtdIy7eNd@lBUI4x+!ojo`_%8xzg8k7-I%^hGOo>d=~`d;$_Z1;d)ubg)%7sXO?~6om4EsDPp)jy5mRom zZ!H0xyrv|pg}+Zc(d84@$NIl-`KbQ}+mEo&`s4}o{fj1O^Z5o*R4# z_OCVF`?XK^f35Wie(mdHZ-iEzJF%!1-qyO4gSBqwrh2z)S3P{G*NW}7wJAB?O7FCO zRsHgBzqhuHf8S&aLI#+FlO((Wwr5-PM`PGW3j^o@v+n`kZciexKIo^qAv! z4n4chHeQa#bIg{XGJaoPKYsgRo$crRmcO=nu089zR(W4e9lAagm*-{9=hVeXDl0?z zDIe|B=A3Thw+rgJ_~zUk^Fmgy88c$?`%Rsm8uOOpV9e1;f11R(F;l14+1|?PVN-3+ zn>zh(wv30TW;yDQPWp6Guid|h_01Xo+|WS6fmpZvk55ArsgU)ns*Gvzo}rVgzz#(8ddoF6gHl_6uCJ^3xl zab`Ts*gJKsj}|tMwU-<#u_Cs!MmwR?M|-F^Y-d>uY7Sofwe&!SKUze)LFrLQ{gRpW z_D{kdKC}F7U+T>^Y_-q(Hea6!HlKcT%$3hApPojIgCV^({M* z`X?>v88;)V2ZZBnM8eqe{EypxtxO?m$?(Cq!uKq%~;U z*X?NP*M_Ek9igf6H>sceW@zfyhNgbKC`I>9_jbAY@Ll&=YU+fr2gj?|9GqKg>gtQ8 zuJ)F{Uwrf%+S*&{0^WVKp$Qk(b;(ab2hfDq_ZhnS!xmlT_g3EgBpM2DzU9lK($Lde zeEE;$sPN_Q8KXKw>gStkRPUOj>fQFJ+OVDPJhE3>Y=@{~Soe1voAlJ3$u-kYr!GV4 z1+6V-?(B|R&hVMv-E!tm|KHI54Qo!W{R7_nhW2-ouYTd=GW{R%)oqOKlzp{hWli<$ zW34oHLiN_k?*W=)w5N!`cA&Odi%crwzmHMiOllC_X4Zet?a)&?R2t=TGkO0 z7WviMp;uj;;a|y~wep+8D~oev-B@LuiHCddW}6m}vF3f7MmD;&-}#dmbzM6VrtY+x zvSkik=T3i1=0SCnWo)V2r2ajA$27TLP*?TAUrW_UF0AX?+^1a8==OS674@uU>RHXy zvzn=AHPgVFu)!x+G;yMy6-}b3XGN1F>T3>en1o#=vo`Sr>$L>?F;?csG~Iv9rw5N| zeL(f`%Jos3>y(qMX^ya_In0{oFl(B_tZ4*m8o`=Iu%Tuo-! z%4HPi2zd%yE0l6k1SN-%DnJLqI%(quKW@c2rx~6*hs@B%F zd}YThCn7_tKJkv6UG$a{ks(!Iw>Ua0kI0OwPb^gWXr05?8JSUCL}ny^Q+nH+8Pyq? zQQfkXWbZ6*_nRB;dX&uQFHgAjGkUt?$MTW_hI?~aRP9JG?m$RqE_>Z<@cSjAoJ8Ib7QDt{WmE9dR?CxmQ z2d}bfnsYOnGl4O_&lpcfb8e1d zy@mGJW7e+7304NDt*u&{zn(n?>@isH!zS5dz#jeBBP(lc((ODw#_f95=8k{c=7x^j z^Qq09_$B)}$82qQg<5R57O%j*1SOf`w6iZ^uQ$9xt?~-B$}7~?R6kRpyh1Hrp%$-D zhgYb>E7ai?>hKEncm?Ta+O+gs=nRVUOY%Zwlwzc1}532fY?RUKQu}OzQTl-y`QB!?l4*H>XS+}nBd4fl^Vz~PX z+|m5$A^hB+Q!jt7|I0p@s+IUZz=2d8$i*BIXKkep}V z4D$J!<0aCLTlu-_?Tf;G&e!J~zOnkcH^aWMIo|vb4>-s0fE)0DtZT3hxpxB9k3y2d zr+7fTU~3N;iwFG1THtxL2O+&;6khPCPjb5WX1F~8Zodz=@q(YO_ zFF4>($2?i27o0>6(1sU0=}tzZ7u>+k(#id2>z#~9FF0veR9+;!lW{b{3m!GRAio*w z!=r{5JnD0$B&f=wgU z{{JtZ=(5eVRo`+;RT`e4s8Q~GG_S?puc@vnZ>^;@YogPZNbQ{4!T27joi*>GX^ri~t41TuV~v z*R}G1mD_7O7HcCsVdaG#jPVhkuyXKM(Rtp8I9+++-tQ|;-}OZ1=E6;Zjq55aD$?ZL z0QKQ34~E~gSg$m%VZXIrk=L!Roxu#+zh)BNCpc!TSB|Om$}zQGIcBU^j#Yi|L%fX9 zTkkr%F|sr3?6RL1YVeKSj;X6H9n+O#Ma}CkNi`guB~_xcqMBn+?NFxpN@?rdr3bqK z;j1>S?QW9)8@UVDHI2NX^Y+3|md`|WUGq0BJI-n^Tt=RuL1Q}M8q%qv7%_VT%M_9xH5 z+qqIxdE&LG?4v{16c-KD2TdQ;<*wSBA0$Ki=G_nUcf9IG`EUM>%QCOd^d*>g)MR~B zQ+c9L-Uak_F*yl$)yT8*QsuwXB%*0SW-a><{-#AUCOVeP0B_vMllt$P%E7bck?`Fk z5|MwSMtkRgx`v+I#zSO-#;gNWoc3xk{3OjOyatw^{hB|fzgH7Yh<-cbXWTcw+ zIQ5E&;jWl7#ZmNg;4B`>_0TJ|Io<(Lz5h#9IND>%GSDxMm!St zqo{0+yO&;7_cEz`t_fuG-5DSoLCU+YoO0N6m=o{Y~Be4 z+3LOzg|;cQOEjpy<3+<85+^Bg|A)C-0`gl~r$Wc7JX2+zn`?#bBZv|B@WPEypa9u1+yQ_elYvN><6=-aqL$(o5HySEyfuy_Jh-f z>}M~Sy%dp;p}1$ zI9<>J=Mj6rC5k=R*(7)A=Q*dPx^q9zuBp7PC^4&y9P#rUcgdj~?qKXY{-)<2?v+t@ zgzRe)K4mJs?53C9^s<{?cGJsldfCm$We@RUx9YEp*iFkLTlAMGcGF*yY8^)^yQjw4 zpL^?Jjk_To?AbVMYj4a+txTPEYt^m!1EBmYJ603jNed^slY;N9s<@bA?0;7%X2*ZO$bbMng>JqPb{;9ZV8 zIhX_Qa^YPryvv1m&%wKA;oSs-ca1jU(Nihng0&vzk~VjfT!WvcN5jjK3P<& z**nFK52dG-Jlh6l8<=V^)nKZ@R5Jp3ev;Uxc-LKQqvbTvE>R8d;$;GKWFmJrWBrYV_{&j`Hqe z87a0h|82~F8}r}B{I@}68$1oq-lk^nlDt53;>EU)q`ga?Z3VLx%vLa4!E6Py6`pQY z+}f&m7b|2dUeE%qi>>g^BU>rbdbfUe-UUC?671X1yKS28-{#YU+t9o1zCPaV*1WTC zMenwvcUv_*xYeiIKhyenKSS?6>nQJr?_vI1nEw{$zXkLb=D&scZ-J*<)a>nI3$xb+ zEoSc#TRxT+EHPDJs=!o%sRC04rV5_Q^W#O8LU$2Wv^=r}I#E<9Ul(pA^XqrES??C~ zZVP(1Mbqv7@#)_Gpm+a4@BU-WJAV~=SB2hvs_EWOeY*cs^zKviPR_nVHam9{^WO|= zGxOif{5LcI&CI_Fo`z>1CpI(tM6p@TK1po;R9djaYyz_h%qB3Kz-$Jy8J^1XJz|sM zU01P*R+4PNyJWFR`Mb@Bq}^}+?wkv5M(aL7>pszR|0g~@_z7B9h1N+~T3D?8W3=vL zwC-a~4}R=p?r7a+v`)^aL!9felG$%$_8Xb~MrOZ>*>7U@lB40dcM}_#d$QQ5=I#`m zK9jSS9IFIV31%ahjbJu{*~kdw`AMQuajv_lq~$cwF0oO0yN#bqJ>K};Ip_U1I`?mM z?%x{Y^y%JB=-eiBZj&|V{2!rnAE9#_HQl?>r~5aea~sjQe|MB~!(V6i70kYp*;g|A zN@iaPl}b1op1V!W-6c7J*2IfSHEYSS3NRI5D!^2LsQ^;}M=KPsDir5pg>1zOTA+1N zp?qBh{xXr@zO%IkH=uKs=v<|y`zw8Vuo9j72%Y=LnsfFFbglxOtI+gdg-^F{K<74~ za~nF!xeYHe`}NFzJ+ogAdOfpW&+OO3(e-NXcCnth>w*?@_lWgh$XQFwIxy?NtOK(S z%sMdZ;HW%5UaV8-E@B-mk8FWX6zi0yTenhb@w)HMIq!OOZaq4;UeoO#`gHGy=-h|s z+=tej^RGka)}eDBXu9_UpYHzvo#Rdv=G#GQy*QKEuLZT1*{@~xYnlC8X1@-OhUXq9 z)-v}*u~yAJNv!=+&RSyDfLQ}(4VX1x)`D3JN9Fk*u|{#Ot5`!TNw(lzvRI@1+*($1 zE+~F?om-2}y^qeluj&5xeR}YHbZ#9wCnag+=gQH!a&)d-(}U$c=8n#BC$eA8rz3uD z#ca8@3Nrg3vkx-+HOzhuvtI*8!*lN@g3LWx1l8P~V$D}_){{mf$6&#gwP8KT^2W*N1F3Asc zCtj?A13Im^;9<=}Nw6P51CD6A|AH8X#BZS#7OtG>`vl=J7T2Xk;FZ%!8+G zg6yi;kAt&VOWC>q!^{02{(4Oh*86lj_kVb~|HFR_oQ1{(S2E63jB^#^T*Ww7G0xSD zb2Yd&HI6mJbF3wv?bSuC!?M&p3e}U|Mec_*u4*xsLyYARV>!fF4l|a+j79DfSj^p$ zXBKl09%BwXU*m0H4h_tqfjRJejrVJ-xvTMq*O6JqTB!O&hA-8B*nFz!dAVP8gu6#p zET7|cq7yDkJVmE?D2bFL`wC?TVV#H-vK22i1f9^uisz+olE`Hsmw{Xcav8{FAeW(O z%Q)X9mMM+03)#|T3$#ZpL!%OD#d&Kq4<*50<4XwEXzY&obnii}kN+SeJZQ~TOKDhe z)xH8Lu0V<_km3rYxDqLHo!Y1aoc}AV%zIGI?85Qxc>7YfPVrC@DM^%Mic{%IyjZGq zrHfdKu6Se%T}c#6(Ul}xalw6fpM6-wek@`?7O@|T*pEegg++X2%@<34TJXic6gezK z4(}p|cag)p$btJ3&~OXya}vI+*e>_}mVjEq+?O!-CCq&Zb6<)L$r)Di+g9k}W7Ci^Xuz3B5SK zK(hoh63pl*GdjwQjxwX8%t&5?w(?Hc?+*gHsUDH4;jX;ZT_ zkNs^e!TYu^!T+|V2jBL=JFSmb@7k?iAWL) z6~4PzNXu#9U1AYZiKi83-^*SPtpZEBw20xiM5(3jv{sOkQNK0UZl>tlZt?Ryid zZO+qT*VaP5_W9`Hd|!fpK6*Icr`s2xhg{$EFQBhB<%_@j=I-l??JqO`dCY$v^PdNL z9`m2a{O7^bd204{F^}2nf)=y)hR~DKFN3Gy*~f`eW}hfZ)$Ef*DZ2^DLSjn5 zlz=G#Qv#+GOes8-=X*qn;$2r!LMutO;9asPQ4s=KDRS4p)X=+9^zL=^?sZM~zwXn6 zucLQm=$({IXY1W-=-q4R-D{d2e9gz~(YsRgPR^)9yc-~&VJ~L>#mv8$`Ij*N66Rk5 zPs6kCCW@JTvM5%wcZw2rUtL1-EC40|MqV|R*RhMi6f**Oev$|%-gOrNT22G)62;1o zhiU2js%+N#Dth-SdiSbEuRh&dg5H&&cO{+AJO3Q?ZVq}^tm)ojpYAV4@3`V^f3>5$ zo3xwx7cu_;^A9lp0P_z(B>+#uv$v_)yCg5roOlsn_f;2?XGLI&z!ZTg0#gL02%Z)x zZWSrs#R}Pq7qmd@qDc9>qC--Xiwv!M1+5F9bpcKH2Yh-kfY!}H>*jPm=j=sjU6C)r zU!>{5BA;%51+9Apt$U@ToU4&Lr-jVEkl7c4E@bwF%)Stg7OJ`1MIm$71uf?85ryo& zCJKou08;>_089ax0x$(|RGuF%3KY7FD4^w$EzpUgKzX|Y_92t`Ev$2eT7th2oh#II z`@ej;_h0DTzkGdy|LT0s`3umw0(9KCL9# zf^*3tU-`OO_)8ZQ!x45CIyW1go2}{o**-lu8=Wga=cH6R+ta;-&b@@ry`<^Emwe0} zotuTu$@z4Mb8}x~_A{CNOlCim+2=F+d}f~yN5gaPCT24CWHD3C-6`_Fkh7K?%L9`K zW+s@KU}l1u$q3~6Ng_{iuDi&iK9AYwK_w54hUacm zb9YHjpf&L#kKI>YNRCYhGabxyFw?qiG?y}Ewv^guElXnF1+s?$yvP|ujnCE=2T>sqVjzG%Q*_U6{C1yd^qLc-h zj_VgS-zOxW2a@ko3Qnq-*MoaXf|IVz;2EN^JVP{=JMaFUo_6{Z?&LGhb|;NL+ol~K zdG_TmFCbj=UG8 z4>-(toZQdX;rsGlk~oQWeV4oQ$WXaE4>V6PqAB~)ln&gZcU0o!{eJrYcka}~U+>0W z%e%F{b>E%gsZV;x9T<71RtN4^Q~ph2c3_7);O-8%+vPKOQn)s* z3L(EXuYM@px2}6A`B`4|P`Ea(cObtG?x@pWJ3H#Czc%*LvA+)PLepP6yU?n?Huj&9 zUk7(?mHaGsZdHG6?Aao}4(@g;`C0CE8uB~oJ}2_);0~dZpXCmrA-|LE4I;k|?yD*J zS?;SD@;m8{8uIJlZj_Rr^MyP*7_yYQ2P?xN7aD6n6F{R-@U zu=~Lt0DA!J0kc2wu@YUu0YdoNkUZN?y0iuiy-g zy)KQtCtre}{ih)NPxcozx%XrtDU;jw>6*vOj*_1pr64;>_8IKKpo#t&pbx?ALvZ^b z+&&1m55w)laGTXO97bQ7xebS#xee!=xm_?^K9$wMJtlSK@D%r$j4OvzI-A?xX`08+ zo>h=NEBg!VBe7@YXU~fLswlY44wNUzE|h&Ly3H<>pIxXRyHIebQ@B0pGdy0K`%=nt zeQQUGy>oV?$T;M)j6By!Nv1fVQslM9 z$(_w@cC0-1=h1C;t^Dj-1=+Q-PeHe*M8j?SBy@Wcx;+Wqo`h~sMz<%U+mkzo+jHf; zyF9@}Nv1gAnu`)o(d}V=brU)8D_P_yemO<1x;iPj%+qNUCpZ@+o}yDcc6ol1n5ekj zT}-6qG|(=Q1GjmOP0`Y6Nh`$Xb(SabK8J2Uhi*TIZs%&cH`k~8bJ6YGXt?cv7Ttap z-OfR`b2Qzb%+ICKNvq4KNvq4KNvqUkmtt>ze0Brep(*c0-Y%Q@H$EO z)wMu>XY<;diC$--*F58H&(d^nmQVL*q1Ws|x1GzF5z_BRul?wC26~;L>HZ9#9?U?m zGdqXZ1JdDFI{Zq9U+M5G9e$<5FL`w)%&j<)4!06Ty5d%nNLPH4m^3hHVA8;(fk_9G zjtu1a9+9Sa-BqN~N|G&`^x0|3XQ$)$T_U}+c^ypGJa!*??L)79njZA|&<6C{9}TbV z<28?WJbFDIy&kW@7oYA;N3YX6h1Zj3?|W+0RL70aaP@#UKTdV{nro|#8azychiULI z4Y?=|_ToI(47aV$mXX@av6}jMs}(PuBJB&w#k8=l@Fw`D-2qB5rG!#SDRVr1+QYn! zpul0Aby_MJ)YD-^FBwxa%@#+B&3Z2>s}i&I)Sd29vwnT5yG+&%-=7;*#@E+LyHuPLFOoya&iW%m}jGD=VD-7-j9OK~pI5yrh?PgRDj$tGVo-;iO6V=SB=3#Z4z=_ldzlW_V;tSXYjIia!5 zGAuLeio*pahyNnEYG9x^28v^#I2MXyp*R+bW07qOozl>l2pQ&@Eo4~Gs)s_eg$#?# z`bDYkfUN&_WSIJQ&6D+aEusAHz68gUnx6WkPtSUi-GV1OBEzh|VT*sm7RO?XW3k1t z*y331@b8@?!|g8^GAwh9hSOu<^cXlj22PKG(_^qAgTwH&EHpZT+i4NpE;Q>(o<(L0 zOmS#TFU@`^jPuFocRb!h#0s9_2_7O=941!q3=hxmSnd;qJrhsk@P!=WR0DCUfjHGb zocfwL^)+ZqZy9M9<$uMx#$a7zu&yy!*BGqpZ&=sgtR;huRJ~C z@$(cSe;;sYwnmQ6s zG7?WR5>GM;PcjNmG73*Js&n|-VqR@!& z*+wR0wBTNG%Mq0c8AntmG@_U0|H|YmPXl>^JYi)&0A~)s8J@5T@`RPWCK|q4O2yI- z$o$66JLbJS)9A0q2i4<)j^TrNrqO@QnxE!wnUN)pz%!4)Ge3c6ege<@1fKZ`JTv;( zesm4{qmy_Pb0<`J6t(wRu>E!9^G~#LpUFM>9F~2*#xq!GCC_06c@E3|6yWjrS~g=7^z*0mtKL;p1rG<7naIXyM~%;Rw8Gi@pUyk4I=?w%I}x zOU$~m@KUpNhRh5MJk*CleHhe-L46q1ABXzm_!Wby(&%9kJxmN4E#)bikD%*i<`I=8 zK2FTrYf6i!WISG;F7oqqQIMyL?EBC+o-Xq5i$+?OvbK~~tC;sVF>g3AZ#Xe;I5BTH zF>eGh4@>VrM)?;!{9o|!f5F551rPr?9{zDWJd)~MouAai)3W;_p9xaWi=}NBM7=#G zXT5ufdV92l;2vLs{Y#?WmqfiUwLZZwqv5RgIOyY`kArRk-2}P`bQ5Sx&MGfrCDl%_ zgA=Px`czcf@?GKCqq&cvxsRc_kDB9|aNG zTNoOKr`~Py*uNW3&D*r>Av|>mPaVQjhw#*UqT;cYge-X+slBOxCIbGM2>53r;4mWK zFe2bEBH%E_aO%9CeDMZ@r=^ZZ;O8Uo^D+4O82o$;em;h$F!-qK{*eft=7x+GM+#c; zw9st%=42hoyV2+&VE#%!57Eyf^z#V)JVHN@(9a{twS{6?=%I+d(jxjQH0w%!MP>`{ z69_$m{6rY%lTVv^f&%#+MSe$--%;du6#3OgBR@;&M=igsM~Rh>5-T4gRz60oe2iH6 z7_sut*79o|amydZhdqK1djuc$2tMo)eAuJ-ut%ZN?w&+PBJSKp-+WrtAL72*v=gP2 zLL#wYgFX-MSo7Gw(0Iohk@yQD@fSqm-I{#IS`_POdhRznCsfCmx zN`O*KDWQ})4DD39AE~M7rrvU-$gC?(4VWz=afw-n`U6mZ0O}7w{Q;;y0QCp3kq5$K zfKFk^s2kaQ%aK6K5h8K1*}@h|LJts$cbc|f-$^9iNhID$B;H9R-bEzdMI_!8jkGLf z9kneu9wLT5L=1h182S(~^kHJ?!^F^sJ7No|58x3Wz#~3@M|=>E_#htfK|JDvoox#> z^1T(iT1Db7q%B?uZKE2(yZ9q=v3 z)ZmUt4%l}|4)oY>*hi7$el+)fH1~cq_kJ|@el+)fynBm|7KQE)pKYv}j23!b+;T*% znT#W9&2&GWe7nhG|8_k2c074Cp1c}QUX3T`{erw(FbZE|DWRyfH|u^p`TcnEp?LD4 zc=Dlm@}YQg?6wmkaoX(722TTyA@Fku{2T&5hrrJv@bi8=MGNNwp&=1G%{E)`w8X3% z*}rj~jKo!DBrY)dPCxh3&%N|>Fa6w0KSSte2p-A6DJk6>(bvR~(c(y{Syz3PnJu*r z7(%T0%#>g7Gh)RyV#PLM#WrHaHe$tgV#W4ov(^&+0l;5*)lLBTh_cti6p-q0*+znRelw@E&3m`!o#TS?sPexN@)}ekk)bED+Jy5>~ z>i0nX9(;{KRe6rPBYMaU87+PB?|&o*PHYR$9?ks&ntL~zdpDYUH=27lntL~P)1sqg zp+7`uZ(4-*7MgWsA4O&h?G1$PCL$U!p4HQ4BH|}R#7~HbpAZp0AtF{05v!u%v89Bf z*52~Fh=_L+5$`4<-c3Zjn~3;FBH|ydwKqzilQ#T)gQo@Xw2)Fn2~dhDC6rQ!!AE8H zkvvT|In0qFv#xj=Fk5*2BYCMt4<+WW^m7OO+(AEg(9a$8a|iw0fn4thp9{spkWn|* zQ!PgVEl1RP$~c1jN@OkVX6DvL@R(wpX_?TF+nOL!zSg|=8`B_RoYWX?- zKrZqJa*;ofi~NCH@7^Lna6r+bENGBKasX~-JJimjK)&B?ee7EjArr%V~RSCS@LoD6iW8VczJ49 zjV!O_wd<3cH6-#r>$L603eu7Ty8VdTQ^XU}3lF=Kf_yh)(_y!hoX#ag&4?ZihV2(Q z24U@ku=YV%`yi}+5Y|2jFWzF;MWI3AvyC;V(ZUxLw;WMxP~!*|Un-B_>x?^AP0K&U zohz%WsusKqXWEw6?=1APwZ&%*BHtK9zVUnVjo*`R{GNQ{_v9OR%-&zZ!!O;XbM|l# z{T_Eg`Cjg!--{3Cnhw19(xgQFoA=Y3*YA{^)%Cly?Z({?mQqf#f5jJSc%qqawz`6R zb!5{4x4!ED_X8fN88P=iWF{Xq^Zp|;laI(uHjYaYth<3 z==KPG&Nf@vw$#Hm3c(9Tj=Oc2QkD`*6m8>nL6`7%z-%gJ6 zJ93=gk>mW19OrlBID^P>@E6usx+1AKeoLhNEs^%OMB3jHX>TXe-cF=NQdWBh$o?Cv z+E#jCT8z?zu*EEwtNxE7W2Aqh^zAhZ$v%ub2gyDv$UZ8_J}SsQD#$)IkbUqbb^nHF zIBS`qTXI(J6ux4Erc?^hb01qq+Uj+<|EBKs0wCF`z|9 zOG5o4v^U3Wp}l2hU1@JYg!UGO2C}|fAIAASyr>fc)Mt`2TZ07K(U0=0ATk=NjSXxQ9 zU7j?1;kNE%Ok2JrJWH+E@g;kXU$W=;r4}gv(id>-WzTUhx-Gw37WJN^{{zX#*;SMZ zV&qzrhrzYP$oGkn?-L{6Cq}+cj9f>ITo;X&o?1p@c@@<{0#SOGv}Xe0Sz_(CVC}bH z?YCgME*%fqFlv_k(&rsP}_*-E!h?IdOL_ahI=2_}4}w zElXKP?Nc1Lkc-?xE^-UG$Svd|w~~w8N-lD1M|?_ZKO##%B1=Ca%gscVn~5wp6IpKV zY@age4dVIQNS_jXU)sXu*MO!g6&I0Ty65$znX}+nur)AA_j?wK_Vhw^sv7d6_2eX6t(td^(7+qB_gI0 z5mSkXsYJw7A|iHc6%nKKIU_DkH+ULwc;TlPetO}j7k+x-XJ0%;3+DnMZv;=X%@#Z@ zG3(0bl$tG>(d6A~^iW{(oqlehpBw1s2Ku>ye!TSK#UmN?m6UFX=xbugXmO;}tgF7t z%$8bDd5IM(!#FbUmBflw#EMnKidDplRm6(b#ER9?$j?&xQOmE~OD=K~xyViAA~%tX z+(a(Yms|wxwUS@!jK*;zKI}$(*p2wG8}VUYe3%y>hRixOqZzUMOV(4XBW=$gl(tvH zy#@bU8I7fMJ0YW)^mNsL@!YN>q%F>(blas@GR1u=3ZF_N#G z_*X`yrB+u_Ewxl;g_c)QJHe9=criRntUU#5Pr=$#u=X3U_8YMF8}Q;Sc3l!m37@Sz zc8=M?;>*msviJhi;?-4D0}u6Up?)pYQ=py#^%SV5;A;%3%5z*B(L-*?XmO;VRS$(` z3!hRHN+IqpGo{6MWjy|6#NB1Y-Q~pH<-}dSEyH(ZqFLoy$=Xs{tya0$lZ#wWE^W&YoIEV=2{Bw}TPe_pnY}7Rdqca>;>7 z6T`DdbFV>juSIjOMRTu3bFW2nuf=X!bhIpVO@#KQMQCrKSy%Q^WVX=WKWDWRyfxBS;c#A}I&*Afx0B_du+M7)lOc%8NO zMw!tJ>2cKHX#qSfq!dvClwwK=rPN{YQQ3VYPt#2fbEL?uE1m|-mdt3X%#5bQ{FQ#L zrk|_n=W6=7ntraPpR1AU)#1@Vu`p!RjrCN^kwD84wVpDLAit8()x?Uo!!+>MZxbut zCRV&ntazJPv4mK$gjlg88u?jDKWh0ot|1q>hFs(ta*=DuMSe{#@@sODUt7zsbw-nV zH9qWWeAw0auwUWBeuWSF6+Y}&P-!=MhrQuRG~(Mk#3LqcWj(bd()NPyV0#0%Z~R}& zXe_1ME>GIsqZ#o`L0FHpPReNPOC%o$FQY6pY_7<06*h1cHgFX-a1}Oi6*h1czO6;u zi$Yh0&o)+OMhgomZaJb>W-Uj`-J0CL7liI_1gD@+*l|zaUoqf>`wnV%0B* zRaX(K(C|*Z*JH%RQ=*Wv)s^3YJ>*^XZ-uFFHRdhy)VIh}-y%<4OrE-!JasX7>S9K2 zam_l+y;GCifBDMqh?;*J`dsX|0$siWUA_Wcz5-po5?#KMNNnh^@+ntD=<~#o(c(y{ zSy%d8X0}*W6q>pX^~<1s8PqR>`V~;W0_s=b<67vHgf5HdA;)adLz!7uJrtNdU@?WE zE69C~C#iiN|C{8#Z<6~iBKKWH?z@QGm#?+i--AaxDpD^eu3t`Eznr*!1#$ff;`$ZD^(&y#ZVc-{Tpx0w{C4GAk#XI- zSjM9PACvJK_Xd#hE+FGwNXEO6jCUa!??N)(H_3S4jEb|zv7+Nx(aE0swB&3dt7}WC zT6nON+=+{@71%ZLGn#wshg zBtm<0Lq>}u1+BEV&}^Z-MWM^cO6P}hWTo@TO6QZ6&L=CKPgc5staJfc>4Io@Y$+j2 z9!F|#)}=(@ONqjl5rr=!3SUMPzKke*xwZC2$?Jj3=Z0qsKa=6-CGhhS_<0HZyaaw; zf~RQVTv;eNf~RQ_JS{Zq$|Dq+ExD@58({QMZ2n3=$@G&DwKZ23T@#>!m->^y6y6$-TZXOh5rfbk=9A83hx{6 zG37)(|K%&cL$QTqtS5i*)m^9a-vp`Hl!M5rf1JrU}O z_?i|vMWMuSZ^jDEXwi3Z%MrCgGmhX>N<)dn-BMFp!BXPx>%`sHiMy{8cV8#&mJxT$ zqLP-CtS#*&GA5)Zk&7geizJbY{ES@WXXGM3BNzEuM|?_FB9SGL$nsMn%TI|cKP9sK zl*odFI@hPvd_+7ii}We}xzZM{TT8Tk&E%~8HKOfnMBCShwyzOwONq98fzw|a4QEen zpVU&S7M>`|C_7~EboOdWBRLR!U2@>U#o^hbxgIpvgXVhBTo0P-L30y{k}WzK2zes3 zH`{EXy(MN{MZ{9Gh4z+(JVeA-O&)t+B_h5`M0}NqSVBZBAtLfs&|pb4Jhqfj)Y@C_ zAtL^Si1-sC;!lW(KOrI}5)rXot9(34UJsm9Xz;Yyp~Fude(La3ho2t!>A_PNd{lO? zNAPrF$Y^n-)T}F>mYFTJPikf~g(j!zC!T)d=_j6kbo$ZhM@OzL6iY(!5q;&DE&3`m z>#DB;voGXV7}ALqJQrcCU*`}j<`652i511fieh2~Us~lWt5L)XOX)`~KSv*Okv`-i zeaJ=nkc)W8MLgspXt0(1T4yw=3HY!Cd{_cLOvi`m_%IzGrbDIO=-rX^RF8?Qr(TV; zJ#UG$y}@b!YZ;B-O1kaxr2UMh=EJZabyh~>FP41Vu#fUNG4d5tOM|ZvBLl?905LK^ zj0_MX=MW?3M5Cprwny_{zVbU{u5rx*YjBHI3oX!|ds?Z2Yo?5SlmmQwA6jOOAAtP}qg$pQN-k^?m*VZB0gooKET&2^%= zPBhnv<~p$(Lt~W{L~3uksmmNGGV4lv17-{DEe<(}hy|wh@(pNDuz-m8G7<4*BI3(L zM7{&f_j;mxD`qsclCA9fx-?0kIK z`S`H&@nPrV!;n>{W;6q98d*;jMB1MJWo++~>yG@dWi*!3J@t%c;Pw?^J<>X9k0v-< z@^Se#$|l1i0*-UBfpf8ebFqPQv4L~3f%EWfE!rLkof}~X*=7qnC^75GkCmD&^SfE8 zN5}*WI`nc5y_`cY=g`YJ^l~n}oQowI)RkSG6VcPekkR5usaaP&m6K_xS&m&Uf zZ=zpAIDUlR{SkimNBG?z;djr)@1Bd_MPi+5aVaNwR>NCsa?o2#T(2dr*Amz3i0gI4 z^*Z8uT{IlD{I(j(YsNlm_RKBYK3ZglHxbn9$%>uhxE9CYg( zbn6_ve56k0gw771k4}}Db){1UrcT`~ql|%p;#p8U3yNn$@oXrb4aKw3<`z1op|ip? zRh-B*Tl7%Ss)s_eh1M3C^x~ERjR)_I2R{c7ehwb|96b0r zNTf}kp6XZMB1e$*L%jbF@&0Gy{m;hxpN;oF8}Hvc8eMF6?Ur(}nFEwL&V<)z!Rxc& z^;z)xEO>nu(v9SCS_F>^&AO6ek=gonNU0v>7LoF4Fw^i zuB4c5wvb|xSyw#-%$Ca5nlWjyctcukOR>BcUg0df!dZBQv+xRM;T3*}SNP%gB}K=X zc$72oC}-kP&cvhi!lU%Uqx9+&DPFR@-mt|&M^AX&6JGa(*FE8NPk7xEOX?Y6DgKbr zg2w@~u6SH*wtg#PjByqeyF;-%6uU#QI~2P^u{+Xjp;Hv<9??Ul*`kMHv#xq5Fu&J6JC@YUFTRtL9qJZ7A0C&Ob;aXSv-NxF zYmKv@*cFOhq1Y9QU7^?wirtWI3!UOn*9a+2G+XpgYSvW`WoAp|0R~->;lC&D8@lC4vKL| zx0%jjc%J*-5FWHO3j;+}}sl!q)xpnldSIMW+ zPknWE$%zSudX4EAgi8)5=K^e!4IuskB*a*c&C^kZ|35rcfuZ2!=s4+}a^)S(F zsW{ergdWPwBPxy=`0J&=rQWu@%A2sK6GX8SM6nY@u@h(A_=g+6FR3}W%Py6>?6SDa zuKYL=tceK5*A=qhc4ydE^ZlYFjt02g0GAu!awA-Bgv*WCNHY(yf}Bu8v;4};x{_ak z$z8r6S7_FuSP#W|C^kT`0g4S!Y(TCpbV@@;MyuqPYqpSIL8~4L&6bK`2L4hR!>G3{ zzf|sI&-$7e_BAoAkr>uU4CCuT<&EE$472#&R{1evSOYPvff&|63~L~Uecd@SoNL_K z45w@1bUmD|htu_Nx*kr~V?mJ|PK)4hp;=clEHYbsK`vm{p;!yWS}4{+u@;K8P^?9^ z#%_j^lu=hQOb@jjDKhJ-hk)5ahQ((6BAL^IXj_Kmb=Y7%Hdv1h)?rFVVyk>* zqx@*6a5<&N4s+IpGvwaZ?Ag>y}>JqacYf;LAOvm+$vfRa==eSD_ff>(Tjq=WlB^lZ)do_wHX=rpZ&bgxw5wwKfd>m?n_VW6%(_{oqWbM?xgY8xD%hhCaw3ek!L@DOi^%` z%~@~MO5ZYTCFSegiS|Z!5+#}9v^Tk3lz576Z<;EsXH%^t2)G3-?m0xCU z;k=m^>O%He53&Jd1IPxD4ImpB zQ-ea=6xt)ABvODBAbE>7C5e(uaT@3@La0#+ zg-#UW1^K05`CGD($ipCcUnC`ol1y=ecG)=}uEmMNYLtf+I!PRUQR3upPS76vL68SQ z9t3$1$wFdw zfY||N2bdjTc7fT&I5<;DcL%s6u|wgK#SU;zaEbP6Fx6nH!R!FD1I!M_!I?^~)!>pv zwZb_S&Lw0&+rVrCQw^pXOf{Hl#=)6NqT9eZ4V+6<(_g%h{cHuZ4a_z$+rVrCvyE|V zQ#hNDIG3QMWVsETE@VGj!E6Py70gyJTfuB)99tDGR%`_qFK8(#ZUyHN60-%&7BE}D zYyqTEK6__e8RbZ;XRDr2t9AR7+Q3cK;suV6!RDnwp z60;f1W-yzvY$#Ym0&i4*$8GM zn2n5sGnM=*!8r|_OKhaScp>|#08TF#Ixy?NtOK(S%sMdZ7)Kb_MXUqo5$hB#QLF=(BqU}nn6+Tmf>{e@EtqwTgEN)< z)`CkEYZWd@tOb`WBxVhmHDK0&Sp#M*n6-?9GnM?-fJ+i<6fRk;0p|plXb*x3f(e3I z17;1FHH?EZmHdL>l0{JAoC@a>vL9kL#R<+uiKplkkDW7>{8oW;8aS5-(qFug{j319 z3d|}ntH7)Rvx;%7QaGECIG3QMTF#QZP%wECsU^%u+B*8Alk` zMJxs95la;=Q7i?QBqU}Dm?dDAfLQ`&37DmfgEN)x#L zOUQl}f>{V=5tv0_7J*sBI5<Fv_OB51Q2Br*58JIFKWnjt}M;O;dl!5bzGKEVNW#E#8#FT<5 z1yc&96ig|YGRDD~N`9r_5=E)PC5cjS$wFdEz?6U~0aF5|6ig}O;7ldI5^zbPMB$P} z2{SoKxXkLiQ5?697{TrWi~ym}17knM!^E za83i~62OIpl~)JaV|ki$u9s-7qXusFhyXBz!ZTg0#n2| ziWDwZ6oHEuw3Pgczmmxkc|?K2C5i%YNkU>~ftdwn7MNLJW`QYS9Gt1-Hw#>%n5A$@Vive$ zAu;)2^1A51=&e8$05OB#!o`Z|;Nk@>CBNz5JVIioftdzo z8klKdrh%EpIHoC_T}%U~3tCEk)4(MPiJ1as3YaNirhu6OW(wm7i7ElHX)-iDI(CC5g%4l7+L}&L$+zC1@%6O$4V4*-ti@ zY%tkivcY77$z~kc3KuJ~!Nm(&N`BekJVIhJ!DNET1d|CS6HF%K$W%DH$ONYgT1tMI z;1Y$z_`&$W_`&$W_`&!YM;O;d_`!LEU*QskA6$})gGmSDXB?afU*beM zxI~eza7iK^T(XduG%#sk(!ivFNe7e8I5-nrSCIxTNu()UvPc8x6zNa>ZK@;nnZgh?d2$c#x>)-)rzW9QFZZec<-Ue z@ico*PqXLrGY^GXj))mzR7`S54QB>0+s1}-aHP#}t1=WCAhvH}`j)vlBD2|5WXef?m4x_`PQ&iJKM(Z?r z=T7qxbRb~1pjvF!p*RwXBcV7FiX)*o5{e_4!^jA#{*cjvYQU_ku@;*xsFs*@D2{;Q z2q=z#;s_{?fZ_<|5J@%D{8Bkoi_N;CT4J`KT58sz_&5|TzL>5!5XD#0p;~5sF&&D- z7^B5k(iPRHzl-XB4=#5|(( z)i{E_4neytzVWH3M)6%wrLRMbv9|j)PenEAFL)YM+x=poq8i0l0vT&z^j`^7RHObf zpfT2Vzuu;(M*YP$gKE3qFH=;b_-2{X*FP9k+x=3RqUtxlNT&4ljxg5nuSN^1e4Wgo z+V0no6xB@gt4B&-2SrdVF^@o1eE~^cCqZBN(g~%_Z_+5LQGAC6s%7RkX`tB7cW4yV zsJ}g9aG>4qgD9#|e-p%@+U^%J6xArciU9|TqW>0#q8j!0FO0Fa`@VfeHHvraGuC4B zef#7C?Yv`OQT3be(pUQ0FG915%_C4PG3(?5?Y#S3QOz{pwXO8EZv@p6^9WQ+%{uzZ zo1`gizWrNKjpB{pP%Sgx{td+&plI=)Z$&lgcY7PsYWH2jifR<^4`!@|=DUQ+Fxq*4 zu%a6EJA;j}w)aQNO#&7;C%l%28DP z=9_Pnz9vOzR8o)B|Ju&`aTL`|^F269UlSv!mY7GBz8Xi+*LL1pqNqmwt`dU- z?Y_A~QH|nl9ZFw42Gw@o(V?hD{ay}(YP;_NP*kIM_Mfp9MgQ!-q8jz{{>E6_eI{E` zjruukgKE1^B`d0a^T}eRuNQ=|M*eEFl)f5u^tGMmj}_HS^XW;YujfTjEisQMeKn4t zukAd|si;Qt1gFdg&NVpD?vtB}YSd3_8dN*&c|ADLf#>zqSUdQP9y>Rk^i&#S?Z8uM zYOEc65{>+|lb*d&`Wp4KS8A*seBKIu?W8A+7%NX0{rzv(_jb+Tp1cp`y>i%0?&sMx zwu`4FW|cMH6*s$w zJ9GaJduJaXMRooEO?F|>Vv6EZt)(e3VWmn@)LN=350UW^sUljd2nIwfA|gK4(m<9> zq!>|D&?=_ux~A)PrDBm%rKl^54`4(dB4Uhy3?c?Z1O$@&-goxi>||qRmv0t-{!w0z zdv9j;+&iCh&gYza?#{0Igk${kb){ZD1nJdXo%Dt8!kc7FZ{~%cUB<7~ zF3YQoy~VH9z6GDYmBxExyf?;sm-61FymuMzUB-KtiF+2$cs7sg^hDAdNO=P(QKUqX zvJ@#xk+RgflQ-hO{A#shN-B5wrpV9wmRY~~*`-N7m4c)UJ&|NRsrwy0ktCnf?WFEE zP0gi^zT@*uZR$T+hlbNLNpFMv+vxBubodrJdC{y~QnqzoXA) z9qwq{Aw4A{&m>*)9XylNRV&Hf`}U#I+P6H>l(w$E<*B3$XsC9L)KEsAO5%y3L;h4! zSFK-m&AW$6L*MdDQ`#E(mgkZ(prOStOATf0xg_iP+D0k$kUy7XWwkt+bf`4e=2J~+ z>rHcdGARQZoLece&e)Sl*0Z$-q|`(HWRmrC?Y={$KYhQ$Q%z~>&~SP(DFZqj?vrR| z?8&5Sztbm^Mp{oM9V#8h_BcG%l(r7F-40JCWk82HTci$CKAB{#PSSW9$wGCPlp4@> z<^?&bI6@p@jtEDkCa++H5iobgua@f{*|XN`&1bC7pU567m9ToxZ^iSZI}eo(9iLcA zTZaa}=Mvk=6M|or=IdYagy2^^A^4TMhsHBt$7Mi=E96tkAiV>mcYyQ`klq2(J3x9T z>)B=;`GiloDKk(I4ym>kk;1AsTA-@()GDnWiSG^_PU4Dzo0E!|AHW z2w~N>Mu?~$I;>P9SWoHhI8-`}?Z6Mebm!||@^s;sJYD!DPZ#dw=|Zfs?Ny<;n-(j( z?fBt#o)Fy56N1}$LU0F92=3qsK@iV`4lACQ9uv~Gf%G_ytc6e!-K2^*lLP&y$1oR4M8YMu*1d_~GaH;Wqqm8-BPAKiq~N zevug+4xS}-7}2(X^j47G3esCadMik8#f$6+m)H>YtG1=Xfa+OK>dN;ZaSIZ+AaM&4 zw;*u~61SjR$>El!WLws~5@!Nt^BL=NT(XA_tJE3mN!=}nN{6w}@WZY6;a2=`D}J~Y zKl~g&{QO{asBOUyx8R3c@WU?saer+>IZwBejAiWu+H-q$M zyl8W?=lM<9ma#E$CYU&5eO^eOIZW{3X1;6hOI0!QeChTU!A?HdDGEDzc9s?t!A?HG zP7W0#QBf%MM#=Cz`}l55o;~;R?0J-D&prG3ZcOp)dHQve&3M;lylXSwW#U~X-euxl zrjuqYJE6+aT=B41t*B-tDjvgw+v{rOZ&QQmCNSLurklWY6PRuS(@j`+0=nMEf+2JlIg0Fq>byV>6cZ9343BK6`-+T(+ zdF@q32C7j z%U;V>k24|Fwr~xr9%m{|aP@tmaP`5&QJC0MUz%S86Z>G|C`|0x{@vjk+W?bngh@8S zBpYFpjWEe3m;|fJ0IseF8nD+#C9YLk9hlaEX&so>f$0V?-GCiSEWxPCth3=dUG+E< zR&5K{i0Z)uescrga{IZ$HA-yqY{Qd@O+I2%l-T6?0#6pP={vGl?Gw256S(ygxb+jb zbpzbG0dB>zGJ)$4w_vYRB(5Q?7EEiwv=&V3z_bob>)-~7rDc`1He6?zvd5W-YFoHg z+Heh+b>Pa1Kr*D$Zz-n4)yFzK%D0Pn4q)wkyNHi(7m4!iBAx~iNuOUohF?F1Uq6Ol z>)_Wq__Ypxt;-0mI|f&8uUqlC#5Js~2h;UnS_`JNU|I{NwQxfMy|B67hHHiDfoo+8 zT>YwNWqP&5t*r`I&sO3V(cDKgj}py2pA)x;<~|Y4Q{w9Q>!oet+B~+?FI=X-D*Fg_ z{s?xig`I0*=UUjg7IyxaJ4m@IYp(4lM?h8ow<4gmYqO)Golk&jE^iPDzccA=s9Aa8a=0sqfPYEj!LfQtOf~VfYVW_zyE}^R+MXn<`uE z-#1+J8Q;lLm-8I#yh$M&B}4Lj>dr4BL-LU!Mahsnn~8cNLrUofMbxN$e0x@uZ_n~H z;zf;k5#OE_72lrKCbDX5N3FJrXxe_TqwpKPgMG6d0iP)lsDC_e@mOvRmRp16)?m3c zSZ)oLTZ7-!#IL}5{ibZo6-MGrFmc8uo=A{qu-=ea15Nkhw-;_^h#f&OoWPh`NSxRx!>h##zNU zs~Be$>&u+W# zc{bsD)rA{5J|Gf*qR=fO=k<~EM#*_S8{iOfUf%{dMC81w(RIp#+C;Z`Y^OD9`@LdE zw|`2Ttv_bg7Uav6rtS1ta!}-YJqU3O%kBG$Na6Xa4rNr1#Lup&D@h(jM zE=*nxlUKv!)i8NAO#Yse^`@Qm)UB8yF^y>NfaePETmhadz;gw7u7D{dj+WoQW5cw> zhN)k*Ek+2KD?3=QitIV1{v5TRw*F$viJ>cqp(}`?D~O>h zh@tNiL*I4MpSVB!YC?Ml4toaNxYPgASHQcp3Iio51P~e!e zh65}0)ik3(t{o-U_IyB$B-i$lYe&ho`KGpXth8MjjpKfVg9fmKC2G5 z4C#Dwn4{7*g8T%qtf!a7KM(Am&Dd3{EmsoD;YKXfcvrfq=J||tb=`YD_pua^f@)o(sTjU~dlZ(7fF7h_H$lC|QDaJA)%Q7O% zn?#m3i7amtS>7bFprOoiO1I~U=QVat@qHkCVem6V+ttbsJgbSetTueCHlnOHJZp%y ztTudNwUH9p_GL7VT5Z1{)J^`1Uzc2CM-B5W z60y;sxioH-a&0PmoCzh)SZh;x2J4NOONof@D~yZCg?;40QF39=Dk37eu#a3gDsthJ z7&~exZR?FKB_hU%h%q8!jEEQ`A}%8$;=66<<7sC!)sdz+O5hm<&nS5E34V@BF!gf; zv;=ZhX4Ho1bkzgXuxiUyR8(RpY74p?!LM*lQf4%D-JXlvkvl^fjc=vEv2hv4Vqzqp zXP0|;tXVwO#7NdGKGrNz)-0a)h>>E=lA2}OmC-ovcV~dfoA;T++7i5d3Euu1-u@ci z{u>#(`R=J6G(hsRg8@OZ!Kk>(;!C|ntlE66+M=x5Jj;o;tlE66+M;6BmJ-?aWi*aj&43>a-po32 zxg7z|y8?l3<#Bt&au;K{i?Q6rSngshcQKZ`m?$YN*75?o^-eVtX9B8iS#MDFu-+;Y zuJOI4xW-2=93>a_yiG(T7xs}0N6Cfxp5$~ecG6JV)~hWhA}%H(E+!%_CL;cqi1=S3 z;(wj2H|>mO$z1tqVDNkyJYNRSm%;O8@O&9OUxq1Oj-w8yep9yPDk^a%m^fptqF$C5 ziW-f|Xu|3m##zKTix_7S<1AvFMU1luy(T0E%tbc#DN{XWQKj0J{z9sU{=()WV#PA0 zzbLB^&zr;wRv|uCAyHN#p0|hdt3P4;Og&NM&qd6 z3}iI*PsZ)YouP~-`li5f#eX>dNsNpsEA_;Pk*ryKtXZP0Sv<>#k*ryKV$G7$O56AO z564fMWq`>e>Nnkj+Csd2A>O_aZ(oSFFT~py!8+2*@#~ws>hj-YFi#3Ry{JB zO6C1XUx4%lNMC^T1xR0r^o4MZlxi`@0^11FP1)m2ShcMYBB}?cRGJHkyKg9M6|q9` zu|kQmLh&pm?y^GhEhX-X6-sJtIq5oWPKhlf7x_22$iK-&{!K3OZ*q}E7G>4uc_STU+n3QeYPJ1-z&VB<-UmJF2HgZ zV7Uv3k_j6PnJ?O`cZTX=y%E*6thdr;y?%265%E=paga_yiPb_hzp#oH~oxe{HGGru=WCYz5t#tg6E6i z`676}2vbNLEx&)khG~TH=EGt0 zk&-fcA4H9&y8a#3Q?J^6FZ!DBy+WAh`&FZH)NV>lQr2jyYiGvo$ep2##`CJcadCtr zAU&cIKk#z|ID#Bi93hUdCT-vHEV~~}RbIiFfNEQQ5L7+Rgv@#0rmgmUcG&R~-EFdd zvL$Qth@uZ_2h@<0Z}n6KAY7o;(9f zh0MseX{VjJsne(R+tf}oQ|^T+_rjEWVM=~S((?^W$?r(|#P3M9=}XDF)g#2J2(cLnUe60ZOJ)8gD)UsA{cEYrn^g1RmDd&D(dL_pTIgAQF5LPq z80&N4)fH3I&~mQl^Stf>esk@`t$78}t$E&6{N~ywesgWt*6s7gZzE4#tnR;vx`B_n zL6o|I=fC8s)D3*p4WgoM;4t%emDN#mDdUXeb8KzK84EQKX+}zX9zgB0vldN<~i44B18~S3Qfhn$K8!XR?RKM9dJmud0%GeN+jeR0%w#UT#P#Qh z>(3F_pChh^iR);o?X`)e`=n1xw6Fu^F_s-z9%VfNwa+1;y99I=>BCE!B)M^I&V8twIH80x{@Vz1ssQ6dh z9p3w)LjX zIrF+zN=!pq5Ilq683fNN@T>yQDwraHT*wUCFrA@#U>Z?v3)4!oN@6JLq-s?WP)IXQ zfN=th6J(qq;{+Keh+d_9OG`5MviPmSls(Q=wiwH=dgw1;28k6fDg6~u3Gh(~h*Amg zEF@M?3Gh(~h>A);O8q%%KW+W#&k|{$CDJ}iq^%;-RuO5dh_qEs`b)L~;~6;Y88|Em zhXvuVARHEi!=6QoL(V{qK1lYNYf#fzX!kwOB7Cp1wxK!tr@QmpCPqp>?fWF0qjpnb z(#*nbJ<+{nGT#O#qO-e7d)@tv{(9*%#_R4Nd+&Tc!Tl_I@6Q_IcNEkAEZahXIOdQ22tt;o|n?HQm38Ylp1h+g1r4qzN9emyY7CxJ%G0d z@b&=S9>CiJuz13+Bc}YUvgPq5HjnqKw#6<1)gz;+Qf;LBk?u#jAL)Li`;qR4Yot_* zIqV}$RpW6cpxV|5LDhp(s!Ts|cfQhAlq!MeMdB`10v}a^C{+T_zlgh{N|2IMd``M< zQ(MVw5PO51h#ZP2;n#l4rk>%-3bIRb? zi0A*ZbBb?)@P)Zlpgk`rWIZnsZK<62sGLNpoOtFFZK<62MCBwUvhB-g9JQJOKUiEw zt!BO*f#{0@fypwqV!4%AZY7pmiRD&exs_OMB~enwXKd7O%C=m=Ce8#CXRH;hJcIRy z%t|66HHP^5r-(JZk2QUiHNEGbL`2r~KGyV6v8GRnv7?64wqCuGh*(KPtRy1-jfnU+ zBI4hOh<|gk-t;q?`iEpj6VT>@=Unid3!Zbqb1rz!g((uq1vA)>BfoF^FP3C4MXah_nDCm3fgdX@5#7&M=-ja9CCoC&G6HC9;l&|k!S zf>=QnBCbCl>-H$?cF*&~3fApD*6mT&?H(#psrBcm{j~LG%q16@OD^&hxyV!GB2STv zJVh>o<+h!XiaT#nCw&4AdlC+N5)OM34to*~n+u1buZ(6i^Cs_OJvGnndqw{gz8Bf? zeamPZwVQ#AX0WWHxHFW|_?{Oy_FB)u6Kv72veGCkZqGl6k*v6Vthl4BxIGbKq*!sM zW|?+nG>)In&j6F>$Q35u{y5(LINts^-u^h={si9s1S~GS+~N@V9JIyQ(@ojqOjxxo zkB_Jx8I50gKhozQeGby+ApLQqKaTXr;hKb;kU7W3DKk`$5hAK>jZmpZfK&YDb8!5HrsOz*jMf)qc$Y04t{z@+LS8|aj$VHwY z7lBpN=M?=hBFke$mdA)Jj}uuQC$c6BY;z{;Q0Q zVeL^Y_faf&4wgFy%bkPe&cSb_#adqQsLgsSOxfd1Wee-|s~*-HF!{Wo?^$)9KGxS! z*4LgYA|mT+AM5KV>ub;7)56$ELv3Q59LtQ^M8w%d#5qL7IYh)cM8r8n#K)YhH|>n3 zvQ|C$AJHBL&qu-YQSf{eJRb$mM`4NtauM@k8>S^TO#P~DF+#w6RAMMQigjPo#zB;{LLvX3=Yjm(*VYFlFkRS*4DnGX{yo>BUXQrYkXi4{~f zd{j1~R5m=%5-UVyBc+cxYCmoL#U3FSd6Zn_QF4(-$weL|7nw~iGTTXi$yT5}42L}o zhdm63Jq(9E0*5^UhdqLnl+n9+M<98ppml|K-rz4-Pd#h*Jzo{RH*+rEhaq=pz9%&r zNA0G>BxQ|eUg1CEcI3`bMiUJR9J{^CLABizP*&;*5F=S}`&e;DS#f)wAx5&|_K6jD zN-J&Ou9M@Z^E1HYjWS=s+aJQ)AHv%o!rLFh+aJQ)AA-f@iVDB>o3bs}poufV#2IT1 zD$kJ7gw+|O&qVr6q|Ze9Or+05`b@YcAtzwYwDDJ&>M?eeYFnHVQav~&Y|bR^`jxhd zsBHMCY(%MSc%CNiQrYlP*@%kDMrv(2={jvr(H|lgd5B!(A##yfzmb_9x^76=qp#O)Ewt-x|Cu-pnPw*t$p zz;b8eH_~FU(V!`>w)~@9^*9q!ZOeMYs)zMP%nBl+sxNq>tgk&!5fNEm`&eH`Szmi9 ziHKr-ozi+8HI%mX#wv)24-gR_AR<0MM0|jVIFpEo@3x(fr=8KvT)bCeTBXeZ&l%u3 z13YJdX9ajxz!VZk%kO8{7-708dz=ZYwuNcLoFVO0)Mzf3Bls24j5D2arZdiT#+ku5 zGZ<$EdQC_SnbU1!%}_nYim0|VR;3yl{rSxq#0vSTYSvRv5-X@|_^50|scd-W5-X@| z_(WwRrT!eXpSJ$A`^iP_Cl|S&T;zUokqUB=3UU!FxNZH3JGa+p^uNGie}TjP0*B3j z!)Cx?GvKfpNJ$yJ4zbYm#V#V!a#T{kE?RkP2$%@;@iaRP++$pWJeHl&ka~N(L47Ux2+XlmJ zgW=Toz-EBSS3DqnKdhDG?d5p;bi92!-aZ{~pAL&lFSj_P+~)BWrtER1vW3U{Rga7& zsM<&`LwY&V%aLA=^m3$^!!-#x5wpxTLWykzziL~Y5>P!jC1{otcOO&Q@=@7{QrYl4 zPTZxk;iIw-BR4ID#Bi93hUdCN0+T0=xB2 zRkqBTfNERT8&o~4x5_LdBC7g=*YhY5k@dBY^>vi>wP!XFk@dAttglmI?5Lr%tye1} zB9;*m%ZP|&L_~v#Xb=$%C+kf=qp48eP3+fv;OPTTA9(t}(+8eDn8Ful0g&^XvMpCp zi8H~(8EX~gOJp=PDx(RjYZzxL<4k3osf;s~ai%iPR2V5CF_mPYE$VGhQBGbr4 zrjd(GBNv(Gq(5=z_Ke1u3WrUF!%E?>QaG#>4l9Mj&{bwLnwuVna} z-?xm$QM>KWXet{e54bZ_qbYhs;8^=2N9fzIj5>Y3x=njiw(k2seH*&siRPTw`etnT zi>8(J6>;f~2snMxy`)gpXo6Y^-d=*Ym*DLsczX%nJ{1<1UXEV}%@Ui(m#ZFULaJ?f zd|37H_=s8ZZCJK5&vVj*Lwt+xb$gsX>E5PYCVPCWgnVNP`NkCTjVa_CQ^+@_l5fD8 zZGT?g!b1G+uKJvI@;7&>s;s4F>vOx6^|R8@vePHsOI9?HnaF2ZO1)8PKb{B4OsM_% zsQpB#{dgWCGZD3))U4aCT~v?L_oq8(j~SV+HlHDKM&do8ziG&@_En`6#=DpC z?q$4t@tw)|&Sb`zOe9T63z_%Y#+jjdj1y69%ZDn}sQ8fIoZL0X^FaK4)BzqK>!F6? zqlOZthT@q?)G1pQqih=uvmDV~Kbz4Gt>l zP<#Sem;s}-T@w&@W0$D^i8%Zx;_#n{!;^`_lZnHViNlkT(xz8h{&WzZM4d>M+E`0X zV5U8SMjsT+-)l9w$^8oDA}Sp|DjiWO9i9qu6Dl1(DjiW#=}3uk`|@{34QIeh20u*> zQDH~GGgBatBcIyFitoXS@4<@i#ftC6itojW@5QU6^;&*$kIj-ROxfd1WeZF8s~(md zFz;pc`4@$;k2+A4I*?}ut551cKI%YG>Oh|R)56$ELup&G@kcVZKa#oKOXhYjncKZ& zZugS8{mI#S(`2NQxzES%7Ci3)&wIf09`L*eJnsR|dti+OauM?`8>S^TO#P~Du|q)h zN<~HTN;yK6`YYqy#W;5{&RvXi7vtQ;ICr5}Dc{nPeXOZ!WX=Rs+ZrpVdg!mpyo*S3 zpVD8HmAhv;k%X1IkCl6rmAmIJL=v%bPw69$+D}`5vAc=G_YjBgAr9X|9KMG*{72&O zAD#8rl6|zh;Iq5nv%BE4yI95D%_{D0IP7kuWQ=`IfPK2nX6^hJyYKmC2;UnF^L)Q5 zl8)LF`nMh*IhBP@hYUZ2K}AN3CYS4+xP-iSGo zh$x>$W^F|s$Wuy0qz>ex4iu#h-0^>|zoC)YPAu(i*w~aMJ^%yIn+SXW=YAp2UHzyD)rYQFD zOd(dVs`s&~kFu)wOeI!KC02-4eMbyz+tz*VH4o632@j1IBWt^QbzCQ`b6@oTh%8L&lS(CzmN6QRJ-p*ONH+h zerx5&w+j~91q*!*3w;d>eGLnJ4GZmNUXB=v-)wb!w*!yJ%8!$FQ(}@jqgk;$Zb$A6 zWi+0t0>{Yb9G^5ynq?IIxsQ97OWHWS?jWMMx*9%O_&lvBtxf}poFzog5+Y{_kyEV0 zQ`&C(@|@^5@ZLUnZy&t358m4c@9l^8_B-2bnw&FJeg8ikFb)nF2M3IY1IEJvEn<-4(a2NJ`U;QV4#GYh^CZKvSP0$=CtEUylD^czpe*o4UT?h zugVxVGq0PO*LdbNo_URDUgODOZgJLYOD>B20qYz`L>fm#8b?GLM?|`rh;%bjQusw9 zs6wUmq5oTslst!&w&1{X>G+eVf%Phl+hS=38=Q^5kb|%BdW}s;v;q~)&7`_0&94$PF=?M zBT?{=L_z8@I&~R?DpcE=NS5NL&$PWjyNS8n#9VG-E;likKQNa+Fqc0#dqFzdpe8V3 zxU4#Y@{OQ;BPibp$~S`Yji7uZoOENHZ@|-U%C=m^CC&sBXI$B!E6-RpqTk2gPu3;> z$~ZSL&JB!n1LNGlI5#lP4QM+dF<{6dT2Fl-k`Lq-<_-vYARmi zZg+m{?$Ug!HU&D>8mcxuV${OY*Q%p!q^(u`M&@!ObGebZjAbrknafz_GS*qEExFCO z0fxN6ov)37A;-XwV_?WJFeDnx9JgU5CF8$}<60Vv-P779!zlsqPHqUI`}D?-8iZeV^k^W!1)=$@fNWz#F?08=!hf6|um$3mdo#8xYmQ zlu@I7nV0Vi^64+gr|Ze5>&d6<$*1edr?)#>ahlvzGPhDPM^GCDSB!!yM!^-M;EGXj z#SL(lX4>g|xYCZ)TwH{s6dfL=ovJ^)P zNSl#jqnOKR<}#YOjAkyQnad5#1(r^K<);-Bt%}|GMlsQX^u=qvA|ByBU>mPyjkHGq`$NI0w`mZNWC+s|Aj<9*a4AsK} zBC2h9K&8zC{O0va3;M)lEl^wV8WY|5v5BSm8ucQbdXaIPyGQIcCoLpPanxnn9-xn8 zE+d)CNak`qbGe?mT+dvtclLlZ*=)q(-Er(dc{nH!2jvlo%5WRf z6{hTQrm_Xne$}&TS1QvAs=qSMHHjcu$F+gN_pwzL{h zJ!?fdTxr#qkgN}CJ>J*^cfLjyiE2`TaVs(DR$`KTH~LJTdF&wnU-;@K(+p5ju(_w$HpgHHMIw?MpaX% zs%hMU4cvkaP}S5$RkKa2j?b4*&a~^ZOVLC7bU{hI+*gMyu7NAAfh(?oE3Sbnu7NAA zfwLq>SPW$6i>Zn|I1^B9i!XwzN2V20ZKPj~^sAA6HPWv}`qfCk8m78BjumqJrfkb~ zX5vgRamHF_$}=!h$h=zVPP;i-cT{}5I<+L@W}^MgM0;vUI<+K&>RsEqOP1nj0ckUm zb`5j6hPhnBT&`g**D{xDnai~Y!$|toM60Xa`LU}@^R?d-t$t6m`n|hH?Dv^wq{Xx1 zxROPTZ_P-tTZHfQlD{3%wN(E@GHO&Syv84x=^vOW6*!#=9F@2pF>0G_W3T)sGntm7 z{@b5vO=w)LFp7<9jgdAUjD|F-_#e=&!uqem`me(JufqDT!uqem_Y!sy2Fk-gc^D{P1qUVY z44T7iNSCV~NQYG0VzaR7Sv9TeZjWykr zJS>PZFElL|EINV=#arL9#*+ellhv0=>R zO6GDUbGeeaT*+LnVlG&^lU7@1TG|z`;}!0F;|kdE3fOTN>^KZ|M3b4#w0bR#CI5eTHbdNbe0>++=Qn;!Z2K*-?J{E9 zWyH42h;5e<+b&19ZT^;lg~h==n=ztrUm99=dNyN7&L$OEG;80)ejn8SygGXe#trcB z4e&5~3p#rX#u)CS&Bzj;QF~WAhxkd22|2L3&=!_G7|R}lWe>r!hhW)5u4T9z7{-%QEibW;Fjb9baai*i za=oBBga1^SgO%=dtHNy89TiuvF$#Ve1;0?s)v4uD)9n!(?WDWp+``cU($5MmB`X+0 zRxqSA-xxwxFodk&w`2vsWiAexcT2C*24jtbvBtqz<6x}uQmpY(tnpH$q>Oe4QGXdx z8&z3BY;^0aKpP|C*Wg78d&8=2+Oel%=#5>E|5E|isel{B_>RH?SbW+BxRtDPFP+KH&YGS2yob3Wso&p78Z&iRaUAzUZrBQa>6ZyT#z z^*9q!ZELKs>Y>$$dA`!Bc3rYQsJMD{YPrUBu)uY&0JU75TCPFuJbkS?+D6)1H7>-@ zFT~F;!p|?l&o9EyFT&5U^7MHvc0P7`0d{%;c6tGJdI5HNA$E!uGs|m(_r!6fiZi0M z&&EdLv;AtfeOpfE__;?%y#DW>nmj1Yr{w>X8S{un`THpDjIMUH5dzi8YdMxHtJbeg zzBg)rUgKK$;ad2Cy#<}U1@;(v#Mr56+p6Q9)!t0&5I-X_VzT-iSCuvht{4PY41y~L z!4>Dj73UKfBu7{bG|0vm(@ojqOjxxozKEzEnU-I12hxj>UWD`_qz^*+Afyk1sSG9x#2bt7 z#v;722yZOH8_#q0fHX6$eskrD8pL6fP)fvM$CRTq)Ti_`&HZG znteOGp{6zP5cUS*x0pZKSQ$SbzL{0De9IKOcaf z55Ug{;^zaMwc2t;p!LH}`(da3u+x6nX@BgrKX%$5DJe6EI5yv6C#|1J8M3%8jw_#) zyt1{=YQGac+iT7DHPdp`d`g^BXIg`wj$3$UGcEl}f$EAS9O@JHrN+=?d!)wdjSYn# z*jv!qTQIJGAFhBO#NI;6h|$j4mFz z1-~iVa=o266HJ`3*4y$7nO0bxLHapJKL_dOApIPqpM&&sV5)?ifO(FM{mN92v8z4QXDNHZAQ`yVaGz) zu@H9r4ea^jpw<`b?~C>K#rpeV{e7|ibBNQ@>ap{n+1KU)<*LV-kZM~V5LP`r zAY%4aTF|XuFK7{ysiYd0Vs)2dbyQMyDydXdd&H<&x2=VP(q-Bn5bKLK{u*!mHQxAZ zyz$p~<2iUEtl+fP_?8IzZQrHTubyxHw<`2i+S#CdHYlGB%4dUeUr_D~2T61-MmgJt z^mJ49I1^TF3+agJiA-y+%C!6nf5thBan53#vl!=W#yOjD&W7s}5<})$wy|cY9%DsR z+ZwA=YG*`~r>U<`%@2EziPvYj@sQ44R|HqzFr_AC7S zSNQp_@bh2c=Y8?>zW6!T?xfY0nU?-b=JHGI^q1J_+1TmX*y-8W>Dfq0nL!*(rj_$n z99LG5m$vpI18>g z3$8ee$RIhwVxTi@d{JS_9%m|B@P%LX$h3m0jr7xzeg@LdK>8U-KLhD!z*Gr25%YB0 z2qm@={Hkp+Qb6@!q@a0*(w%l;G9yuc_Ucr&jSFFc3t<5&+d7qP<02>BB};L%fV3IO zI1_d}6Lvfcc03DqJPUR_3wHeF!7x&+57u}F)_4Zicm~#Z2G)2c)_7*78L7S`jw@C6 zi&`^M>|)_N<993Ub!)G~?l;uyyvF%(=lO6a`vE%p0mcPz=LJsKE5FH1P0LaL8OXGH zy{<5dUCnEl;w0z*OZAoC&D5;sCWDd@bsIqE!T~SGr`0e zYuzZ%ST!wOju2MYFitPV>BTs`7^fHG^kSS|a9u)T!0Z)&pEXvQ>M@Hd)wZ-6Qa!X9 zHhU?p#;ls9T_02ey&9EmoyxXx9xQMkEHDTb5S8t;wd!aaX=_#Qji2|%&wJzNr{U+P z;peB}=chSqwWWm_y|B|>*y%5@(_dhxzrap^ft{kkjAmN>CeK$ss}E}JvxY8www@h- ztS;&EcHf8HLr2ZGKhx^hZFk&K-5K3IjGZS?t(e8p{ONjaU^2^43H9pKybZp2B{mR# zpysVp^ERmaw{6w&`L;LHI>b+<^qZUb9QP@3#VK&bDR9LpaK$NbMK2wh5vH56$C?h#`*p>5qIOL4S-v>7RO3ha0)?072d zcq;68D(u(`c7&zVU;Al4#~Oc*HU1oH{5jTm3f6cE)` zZtcekd*e6Bs8O%;#(o2LvLC>{K!MQ@?(7G5iv55#qk;09%w$@Q`fq=x)o*TCVWjnM zjgdY;U^G|7|B&Xz`n_1c7whkd_4ma3dlIJ;b{;alHV>GgdU!xYwJi^*w0VHv?5VU6 zJ2zPi)H}Tzl~kQdDizfNDyjtv3qaWm%3e_Rg0dG5lIU8DQeZ>6!jwJERJK6cuXH%7YXw=Lw5nNEdwZruCD5x= z**4CB1u zQr5KkjsG}qsqTzsTH3h+)%pV*JEf0S;x~Sd07sCciX+4k)}*gko@n=*smhBu6Hsl- zZ-T0Kn8-zVPwOoC`|wnXb`oBD5?*@}UV9Q=n~&G#iqnYk#raPMHj%K=}neMP%_xKg)z;DX7T&pI|1QTbhwW>S=tA)gw*4k<3&hPi& zsT93Cv8}s1Kh~YtmPc&MBevxc+w#zDCZ9^_U0a=omYtqT$&ECBx?Z<-!|aiT-3YJI zm;30;eX#GOv+rd5n)~=Q_t9p)5T8+dS38IJsg!;Z^*OG9mWyTQV%fP^b}p8ki)H5$ z#}hUjFmvN~C95N{huv2t&S2dk)nm02QEjAmLwYx)cSCwNq<2GlE{vCu6EwToMkrT3 zMhL04#cpBM!+#=XHj zKP$*(F1gI*XUyei%;jgy+eQXkydYc(up4189KWe275+rYav;Rqb}3- z0PQEtBd}O1}6{rmMr$$cJOmom=fubb^<7$0LmwT@`<2)A}F5- z2PN^m zHdcixdz`6kF_vHT&}zUuA#PiIzeS&9eNc_}8hzaPu|B2w>@pST>@Km()FZ}TUHV#e zw2id2s{fd|{Fu4?n7N$DTux*zCo-24oweF>wPXAUcKne$UpoPIJOOq*0d_nAcKk6? zQfBc7vD)cfFQ1E`igQM5pViJ1K0BGbv2{-NeW)utYCa`SDKqBYb7#ga)t%ARj(&zf zwOfQEpsdfQaK-U(#qmUj1S>?$V{LpBl1dSfn3| z^kZQvDb?Z~`v_Cjc$^8SwlzXf^iXD-Jxm*bhskC@Ak4u+AmV~JMBy7P@=iB`uFt&SsF z9Y?e}F4K&(!WYMt&q|)wnvsmth3^dBr?A(o{YHD1OU>M?vnOZtVy3;ADSL7{dveAv zoUo5uSjIjp>7@S*WLh~fg^}@#))>Wl3ygBMNFVcSM`Qg*WBo^C{YPW{M`Qg*6Q_@k zUxA(bP1%-f^~9NA;*7OcmuK*Rka@Jyf^O}x*tNi(gV#94ogX`;G@o6K0-fCqb~Sp$ zPIc0PkY|_TsLQlHKtGzf9L-#gW-iAtmt&aAG0f!{XAej-)9OY>$$*+ps9u=Wk?`k)%`jrDZrYwRxR>@Km(R1o_) zF-hz$rOj)Owvo10jiZ>$QOu<)bLq-lx-yrp%mpiV%AZ?WSgZ@|c%(aDKe9C6I1+X| z5_UYw-9tx<8O^kEhrgtJRy(D&&+4ZNpIs6DzGhmEns0xmmD~7D+)~{c&9sc43slF? z=4k$OeaxH8GVDfpHTIo!_MMEAv4NAZ0rs7AvG3HTRmbPs-kR1S{_T|9$(!Qyge!93 ziX6Bi2d>D0E4siHU5E^lBP<5WvGK)pQ}#F$R&9$fBC1EG z%5nFI9qyF2UY2{9yr!a~Yw8lvD3XCSJ_#f5|$NCS)`a5I&ow5GTSbt}HPg=d@ zNr&4!pu&_r&Q!MW0Ke+t0RgkK(t?qftOa%vys86nqXLcnB3n>2OE!pl` z(fsLpEjQV!*_-j|?D`nF*g!5ez^;$Zu8;9EC##NoWP3BML;O@quKN8yxS}Im(Gjlb z2v>B3D>}jz9pS8w@jL0D?|t9KOg=O5_qFQpuIz;$#@k2g3*~1nkm^CI2dN&UdXVZt zst1N@mas6UB+TrXS7v(Ry$<@qx7FWW*?VRCPggE{S22)o?V8xvdhA7bjc)GzShv!A zjlDIUy*1;f?jEt9I_c`5G@dpC=^dF%#~ZIa<@XbQf5vrpiSPV(i0v(T$M6u7Jl>1O zUDW&1Ntd22z6CO+7aauKbV)q78vAK$w$Xkj{9&DLDg>?c@xxtXo3yhi$rh_!R1*Zk?qn&wZT#;jc=yOp!6;?>x%(b=zI z-=-k;V`3ZoHM-cZX%qc}(qYrcyKE?J!}z4+2Dmk+)Ccrv{7SxRq$;hJFErp^P03_M!Dih5vX zd209r0y{syi)ozD+6QAl7CyMb_kGQZ9QB-%&r@baT^i*YF0)yYb^@sG_|tZdPvhvb ze|=oC4YQBpHI75~#}R4Sq0!l)VW*}?jJ>e7Z8+|c?ahh~@e?FnCciA%C#)TS6%N1( zjj%!^tk4K6G{W?f4eq2$XptkOCxh>WG+ny!$h(DM4f)h}e*6 zMoN7Dzjj<}M$(TLzVpg|6!x*M$=Flv_iF6x=Kew`%{aRmXE)>QW}MxOvm35UNDP>}2`PuVg>egPPi#tEor8Hk-Urc9T%sA5BBX;D$Xw}g+($=cJm$~d^E_<2F zH_YW5=JE}5`NmnRN$bGfu;XrbzP1N;+yguAfgSh2j%YBWnU-tuUgfi~BU}5d)>ZiI zsrBF2Ov_R88OXE-%kTboXSDvLA1P2>Uc<3MdQec?h0pB5XLjK;yYQJ^_{?q?GT|LT zbC=C;%2f})38}WlhGEsa`_BHyb)QX)Sx!zOA^`G?rE*lkJ~ z{r>Nt-m}jkwu=b-wL4$`x-{STnh5+g5qLM~z*gz6eYCG&?XO_%uVC%3VC`M7_AXc( z{bklOdoAngE|OZKb^;^#V1(%I(tHn$Py{3RV1(!%Cj^rtm!lpWIF6X}hGHn%Jhkti z-M4JNZWz+?ZEnWV0}BWzMWX#PU42$>SmZb z;@4w!5!JS=u2Nau1tMS5Ob)$Xb-5x=T|v^WBNw2)R2kUyUt_SOSxW$ffi49}FYFk4Wsr77E%7N@EnS`4VRH9}DJtgNv4Jtg8f7kX`LF~%>IYxOWiJxoy# zQ`Ey0+hL0B-<1}%ZCJoISY{h6vkjK{0+#s#miZzxT3jxD0<5=!^;WRn3f5b}dMj9O z#gn$$JjG|q9vBBz+rqd?^?oa&kh}_sTadT~iCd7k1&LdbxCQMd)iJS1mP2ZIc zjZg5zPw>PIc;W^;aRZ*X0Z-hR867VFtJGmcs|D#gkgfyiI*_gd={o$#j&O;>8-)F; zZRs$ede;h6<$I7=i^N(a)*`VMiM2?qMYpxhwoqxxwv392Gl9ezm&jn`87nHv_DI3r zwA|^|}4nM5J59{#5I{fex{P2_SN{3o4eprhi*5Ze?_~FO+;m7#l#~IOK-IGmH zhkk86NUsO!^&q_-q}PM=dc0`8%}acy?4iS;YFj$2QauY*c@+}ZA#oiN*CBBo64xPd z9lA}(37G3_Bb2EgBUGujH9|=Bte7a@Lj;b9zqhSJeLa4-9zR@gdcwN zUFpzRhaaxP4?n~YKg16|#1B8j4?#KuTv~Un{JaQA*MM{lNY{XL4M^93^g6uAj&QkI z)9gPX)wU20tKMjVs=Nw`Ymm4GiEEI!28lIDtUR0xk1sLJ;saU~L0B5@TG zS0Ql~5?7(ygq*Os(x$@-)nkOp79;po&x(ig{ig{&pxw3(_0{;{YW#3Dez*odT!SC3 z!4KDbS2{G_#}D7f4_D!btMJ2B_~9!2aCK&M_)#d1A4pe&^h%Ik3DPS;dL>A&M7MT? zOKb@HRol{GK=p1GsLJ;su^NfhNUTO;H4>|lSdDJ0oBg@clx-Og6K4X6Ggds5XRLTA z+dmWWkapWTjJ<~+uEY;l;)g5o!ZR zz&nka$ahjt(O2NBEAZ77`0Bg(>bv;ryZGw689{l+xvSM(`)7+v**`wmUj3&p+|N$A zKQHph4EM9I-k%r#WCnlR*Rw2A=6)vY{?cdq-`__I_Ul{T=j@JI^Nj`l=9g*x7Z`a} zpUlV$eaU;K$QsR}Y3^rY%ePm*av-j!(r07K3#Z+8{jm?0=DvEa`=lx7mY&rA+^$(! zg;Ptez16?8q*Go&;6UC=y6j?*;L{ujlX4#*G*5p-x-GmC^n4^*z~z)6Oay zIdW>r-M4mJ(|wie_`F`+`zhRePww5jikTKQ*zVaHt%&>H)p%XPym5TmSE3&8<(z z&D@o*@$}h;YiG?q@%2*MeMK7tDn%Bq;+l>6p1t<_i#F8Q&U2pw_Uz7bWw~A$(tYT8 z|EK%Api14}Gu$cTqmO8V(3hwAKKo9aI{T2`Wl@T|ymZel$GgNng>_y~CG7VR?#O;0 zzQ(xS6*VU8&etI9&etI9&L{1zsM+p{J$tazXyap4lCYtCU*k(URoiK?_qSJ{YFWRs zw<2MAmbFB&A2*sqBWNsPsnG^uk!W&Y+)@jtDP7%qYsac&z&FLe`;P{&j2mo{tkJ0UeWUG-@c<^bzVV$D?R%y&)dI#V6kgY_N=lgXmnrkkIn4qYLu72lj2R{>k%srv&!q z^?GqHd~x7cRiy<{cDgm*r7(eooVY7+^c>hYc+Ua&?m3I^@_pZw=10Hz zR=zuB6OwoBJ#6&$>T?%{4E&MzH9X7R?ak}?B8YpK<1u~_lGr2iYapv6CXXcH6N}M^eN@Dc!_UcPM z5}Np;mRUU&zXuQZQ1tEh;N>2A?%K=!K7kxi0;%qCqZ3UlDR!Krd%qQ_lNhC77w0Y1_r3S4yzT)DAD{5){qE;2rduiuSw1qVG9S zIK9DGJpHn=HDzw8hbbrbG$Kad>5HdZ=kMeEeHWIk5a+GYJH*eIEiQ9EOQd?XKhbK+ z40nFf-kxvuTGlsOxb*ZTXT5e=`I_<##&Ba@SwR_d+W*V*@T3mY>aedEwj_jdwOYMx`*?u)X?-_d>>x&{k1H zJO&V(#7KPJNSr-28ZsUvmirn&tRb#BZR7UpfBaWy?vmHr=1w6ae!cN2*S{>hnFD~m_7Qag8s-i|AU&PKQt=M^P5-&w1FZm=dJu$FQy_-6+c=yf! zEp5RhGUi>fhfk3dHJ*GP^50Qye|5T-yov!gW?;ft8acTWE2|WiaF>GoSV6fyyBI-f+Gjyoit@YS5Fq46nL2{ zUU_U|!zV%+P9qx{KsGdh84sLVa?Gt|@A{XQ9GO=T*csQHsNqLLev2BXY%k?+ zaa+(n!{7gE@$XZ!_~5sQ5Zp@#3!lG>zhn(sJS~2$vGu_|$=96vZ1P`@2+ryl{fe1? z)s=Uv*~hku`@H1IyEEHp5djs|e z4#Rrye?p8D`MHRj_s87>eN|l>D?L2o7ZJzQJ1Ir}wj{+7M2;{7$Q*XGR9_B0iL+9~Vqp14kdiuTrv)#Jpn$^jbT{yc> z`Idggv$q^yylH{A&zWzyx}JFqGNzVXu@o5-cNcX1WydaEe|elMN1H!vv%GWDx4^pd zSsh*3i)PQS*xj%AsokCC8*lWRHLPRSfR6pAPCKv9>b2Qjx!3u7)@Ju{zrp;)y^gWp z>*g`t`%as0jOo{B?b_zMyyS&?FNq4(U-tE+qS!Z?ZGHb!Hu8NMY{A`1{#i(Zu{mR%i8}Dm1nHfv#({EHstX=eGB= z=XY4@9^mdXW{j)&k1x3f%?0oNa|N^2UM=l&r?@kz#r@59 zwoyB#_{%Xz-+jz$vu7QX!&+!ezc=q+{>rSEnD0x+xhgbE6U^7$W6XqPO>De>%jQ1A zH@oIP+A*uo_*&QenonJ`h9hNdjk{}CULWa@)%9|BR-Y?BbzSnntYKPKpJQ2X?X7Xo z@9-5E&fk1&R`LD?uAPt0D#u1PEt8y5_Zs*7PV=*0 z>v+Wj#eY05YvSx#Wmwk<88d{)5fmT_B4s}!nca=+?_2fr@wyQ{3+*k;IDnB zz4xyL)1LWn&x-!9EHxf{Nuc?`f5iV+|8v%`vaFH%lmBtCp2&9PpH}S3?|u5H+`hS& zjUJPmf7{_MSNL`rHgeph6UD54kvnqY*hx3?dgsNX$MbSW{AJ?kF@q=GBKjl8 z-9Gw)n{Q^$=jpCt{V#S6$sg61yZJ?a@h|d6#s6zL{^b{^oIvwjFH3o8;=V3VeQ~qg z%dZ%aN^bqInMei;7as;ewk-ju}08d96ReXDi<5*KW_BINf_J>V<+A=DR!-?ok;tN z@guJvH#&FHExET$;EhZX7;)wyr(4%qvk?E|t*-pBydf()+s!|Z{MRArU&j>xw08dM z^#A!^){ou49+Ks9oeUJYZ#FdDNc%!w@8xwAuQPcq=QY4v~?HPFJtD z8k)SkHu5@z*P^!@nkMmj6R&f4t>bkGuikeWnl|xT&TA*P%hi2(LsM^F`|)}eucyDq zc)YHEpK*9yw+8thuK%E+>1&v|MJGQZD3$I-QjZH^)bh$QdYic^5*V-?dn#S?ExW1|BVO|5Lsf5?FzHVybVLn$qud8^ydQVf6s}u6UQv7q@ zbD1ma-mI)2ACYbS?Rfq+FV@i1O`O!StiPQ?b18p2LHvz>;=TPi-r;X2@hbl1at!5I z&)-hu)iofe%YgFiK~u6Wes#dI0XgDN;(d2ehv3y&FdO2>7wR!KG(d(HFw0XvCZqo z=6MNO6S(epZ1Mc~b?P3o3vJ^)%r)n5&4{FHhRJKh{Vn90ySV0Yc}?Q}W;EZQxUP=t zwsM`N#{oHsc@1fvmg@|z>x3fexNax54EFP~E)>At=YGgDtAl{oUE{XiFfVJsn*&x3 zcwgMNcwax>_c%Tg5{ev2Pn;F5SxdOZ1{P|w4xteRvir-7W^Oa}|@Z9*F^s|t& z{6^qCkM~^jG4|8ed~!RqnvZzj7Tz}w?penx^O=yWrzP>*pJ3OMu%BFy%ayaGp-K21 z@3Z-lzuC@mIdwkQJ<4^{<#o!BN~Fzt`TIDoIlwg~J?IqW%>1Es!$rcnZs-x8^$&}< zQ*rGat{u{)v8nogIsPaEx;8t|uFtRtYC8%Bj;Xjsq#K z_RQmtowMsSaXl&$K<0An`8~H=je0MP4A;>+6Kc5K3HF*VVMRZXDOuaoy5Z*DY+mPVmCRTsQf%rY3J(SM#!lD#Mu7;o**t zXpeT9eb}7CEiCrMjilKtR}EM_V9kKF18RhgiMiDw>uO@hjjhJKx_L}-U8j!tG1t|# zx~}ED_U5|Fh(Xu1x^8f@JfXjrY=5wcGl!PWt-1i|UH!!p*D7?mvd*XJ>C$219eqw8`~RA` z7BD%gDt)V}yQ*h;GMULFlLsN0K!_2Unam^v2tuBdWPm)#OcKbe($n2D)6&!3boYcw zAPKCXtcvnlM8Jd(6ct$(Sd1E#1(tQyMU1=XDk>nbBD=ze=%V6-{r~%@s+j~IyMEtV z-&gnk=bm%VJ@?#mZ&g>{s?Jh}Kh#;8=ckDJJ4>B@hDn-bdvfVYS%H2&o`W%Y);n`p%KWJtAU)_hIJXxY(itsp5|=k7Kw;mn(hCg7RsnIU;(0ru5y4p&VVW z6^i4+l7(_KX^8ys&j@6nt;_9RWbI^}?1&=}Wd#~r{~1&{o8S$sPZYtCf;8jjiV2av@-fyA0S{UqWm5Te%GC+302$Kts{RmA^_ z?30^MK^9BIPob`aw}@FR-hr$khIa1*h`$?^?P*OrAsP2k;7n;+O8hA#&eVzQNc>9T zX%j2NTamK{QKOMHuxNo&$h4>e3WHO>`$=li!8gJWlZcZ zu&keD|HLvT_BUA80!y9mvW$uSJj-sS+{-LuV*i3=7on?;g~VcFCy6+8_9UVML^FvV zAbLB|mx<;RJw?P2vglSDTPB1>ci86>-9faK=nzqs=xanpqNj;=6TL>nP`6wp_BBZ2 zbx6D!GLn-YL@P0GCI`rU6tdo|@gD|;)cYy5cfx0YCpCD_#D5OD?kh-sSS#WAsQFwn z22a=Bjne0n69GjHrw*R3%n9R1}LlH{%*A&VUHlv>{+i zu4!Cccr+rn;}EqbC-E<~h&zuha)hJSrI=jJH{$Zi%6CAtp%V-6@q9kcAuww&=dxa~ z8g)&*FzUrjEf8kyR7;s&ExqHgbX?lpjkarcAkizPUSPd_;9fqSi@3KJ@QUUIgr@;s zIsQz-g@9Kz&yh7_zvJa0=DaSmSQE2^la!fWsT@Avjt_IG5xfb|O_0P0T}3b% z;5vd60qy~i$MM@BXg%-9Xm&P$l`M$K4BTW!oFMaZNwksS6bj-$oJQW*IGK$2k%r~6 zc+p96jyaimc$QrIUQ~869f0)`7Faq#L6$Zv*aW%0(_%5n^Zk^;BF=EKXCRrQxc1ZtUXEI({OkyRUj$zjV#oJ~ zjJ$|5c4WJqk#;o}afYdE_uN>5R>^h^X1fNnU4z-K!E9G!*{;SS&Iu$nuaES|U}`p) znhmCAgQ;0#saazYUj>HjQ6Zd`P;x!S5iw|NiB6H zwbZW=Wc*QJ>E9i^l3JHGFM?Wo9TF_H{PAI_-zt{+MPb?UDru>!q!p7_NlRTNEp>79fG|8L)gEWrzzg$o%OHD5qtAF#*A9scqZR-@H0xzU<1-l;#X z{-k46jPn83L!naNBZlYyNrtFzY-yC;5+_b^k zIQfF)h4Ia>V0sb+rg$6186&K#w8+7q!JuM%3o8tLTe;B*d(K{)0YNB^og2nx&)AId zFl}`=DVu8+h*b1h6VGX>3f1kz}npT^F^0(DyF63CLtcy=0(8RIr@>z(Ust+)gCq0sr} zUYRN4tx}sZaTh-yC2-up_s1+BC3zBkAC`Eo8pC+4(H3)^SPe%{DvzeZ#(E`7fgmPo zTtti=!?OZbU?C9H1Jwp)lPIVP@hG8YIy5W$(X_HZ;W}|Dh&Qq$?7|FHJDzm*O9mt? z36haIGScEf2@G;5qm+(GRe9}E+&WpJjAzXdsjfL;8CzCtX}Ic9$XiKeLc z=NVfyfYGt7r8mNHny8y%A;#?f{WTbbcu+wOBRU&3F6eYu$ zP{5Uo@=0f(98#3qvPJ1L<+(qY^1@{TiAec9EDIL^c0L@H5UGjzRwIR2KsbdRBEr3)9nNKTwl7ivu*xqQJAg_3;cQ8vb3kAvu(jV;Y%H&E8joA z)8AYyXGEo#z9^N+l>J<#7$FKNJbLr}VLVTOWK~phg@t}Uo_FU8{Smq0f)?snNTI3MAfaN@iKv*LxZ`3-=7-F<#&t1V5Y3NB~*kaHZm+W^mLu?FYobJp0{+B zzjmF!p{u8N>4si^-CBSBhOVwP>wEoW-MwKOg^I`*3j-}OVe26^T&Uy*3fYV_3f)=g zv#%WswbiG?=-<;?Pxq>|OV3k{!D?0&1-y?UDkdR^q=J|twX84 z+*!GNX+Bf5pqw5&Oa6mClpELnE7i})h#j4hH5${2z3e^gP%EjSA2Cqk< z1-yaM+FvL_M=E_$tA5L>SXPDU;?NLY#)2Biwc?GELJ`FJ?k=R&e5G{=Z(ilk$`x|e zTq@t19m%HU5bnvAi=yDu9hE)dSYQNEn#oquELAR3v7?4uV(CcuFq5jLbkGD|92Gs8 zyzrM5i+Q2F&lofDnk^PWBE{&b4wkd2j9^&DEu5Do%sey6}|IT!os3g${`pyK!CXqXPW(*Y3W*J|6S?{;okLc`=B$suKFw4 zSGiJ+u(u=Z?MNq+`C{Yw-7>saY*w#5qBNb~gTU$&8&@cn@8hoxBprdqOmP^kQh|(E zxE518lUoo7$YoPYZR{~>%2ZQk>%;W*aQ-jT%}0CkPrOWyz1#|Oxy6)iE#Speyw?Yr zQn8X7X~(>-kTN-!oQML%?+7p6yV|it4~OD-A+g$ylX+BLUEd3(YJT*^U6spperK!H z)r!TxJy%HQhcj8FT`&|XZG$ivL0QFhp;`zjUcpJiLKf=PQ^RZ(AV)T)B2q41vLshU zZ{YyE3E5iC;*DL9NBL9Tccjy;YG+t`JLZDHYG%MdPLR%H)s~YeTIJ|&9$ljJ{clVW z#*{(vApa%6qcl5#c@QELe@QF`3BdkwcBCYEa_hEm9v5$C=wB{4i13N;itvf= zj_`@^jqr&NNBG2#hJ5AF0v)vNhS+vEl-M}5PCIlP9iaKd#v$Yr3pzmaiH$?ZCw@G_ zCpH}>pZEX`()Edr!Q=-9E50(AUa{vL^eD{U04qjkq$ljf!ieRx^sxy2IPen@nwH)X zv6PnGh|^ehGq4;QZ7D5#DC8d64l8l+>D*u>@zxH^c<)D1DxV`H-g#_gnmx;{G) zqk)>H!G|L>4Zej2X@1~3MGJ2_47dQNwasIe!C7;e*eeomPMdwuBT193opKhzw|LAx zMwkkg7L=NiL#Y`wl(xXEoiuHW^xE}=DQWOTx@wEZOnNO9Obe89M)aX&caOMSU>pX4 z_eAKxt6M^^rh;CWT7hd*L9Yxe@NX*g?-pzpM7R3cwXGhr%L#YLUNTTo%8cDZDYF^u z&sN#XO$sv06Z*23j7c#F_a_8pMjE-Ah^dyu+yTMVuk? zAy5o0j0bJHoUQvFvnz2r`}ZI82xyrF-%&etaS@^yIP7-E!Jxy551`dOXjOPW0jriq z`Q9za9wpo%yk6Aag%bf;2MNXw;(skNX~vNEV?gPFWC$11nPLe@F>K?@m`s@qufG&3TD|HlkK#3hf z_C-Pj-Id5?zqbbc#`p$`5Urd@a;!(KSzMjCV$!9r8VTRqgK>X=@#4#Iml81M1dNGZ zof#FZ4F3mn0{-V(xsxM@nTzZ>!tEZj1|5Fna(v?$77PlP2%4!#5v=+cwc0n|oE8e0 z0^wy)dmm1W60@rb;ap^#StzB>`)Jz^j~Uf->Rb!%y-JuFry}~tjP`KsXd9OmID0S0 zj<`&o?^TiQQIL(^qM)(ff^$Bgi%n&U+^)nvhU{)aj8qBv0pd*_GugDd5=lEZiEy#r z9?mpeUC;|&x;Rq7avr(dMXqre2TGhmkLNvR3kkP)%;e0@hnn-DX87oANL-+Vne`Fw z@R-SZkqZIb#YVUQy1SISh-ctL*G@n-mvD#2j5Z|pW59QDJtVbKF@s(~-6CC#nIpYV zk@J+;T4cS1zDKj9Eq>Sscz-&I&!NOtkC~K!hv6_@bzxD^66V4d6v@SZyT_~_XW~+6 z-3jU{_%7Dj?lI#^95BPG4Ihy4d8tg7%+~dGLHH;R7HwG6LX|@vGu|Y`u}&lWX&fyB zC%7-cO34asEZ*cXV+D^3`=~0L!YYUwR(Sy@T*T}Z!j#8s1{L{XQ;`cA;_-DzG*Duz z$7~wmc8}S~sx&YWfyYLU;B>DL*KmRme;X%SdJ5UIgxfu4v>~w%eY}DrPU?4x8FUls zUem?yUZsvAF=c>@td4MpG)s=ws7rNV79!_K)MG!;2OD*kv0iwi0vI%k!CwTfRF{`m zeh!(HSH&xV-Al31&N%21uO@G+$80Umnrrs&7udrMF3Eny9YppX2{C<;UqFn`QG~0c zg~4H)R0w6v@;F_o3~LN9V@xg^Snr5gP4iV<>ZMNVpPEq#+dM|L()LN#fUAr?B^Xg-Mf%*;DyWE9}c-Yh$QGaZ>wBNQqVOa0tD$p)N~lh zLj;c@`3eE!e+H#nkeooksmW0}mLf`0(4`~=T}o~tpdpMrcMp=waK6=1l{==ew+R30 z@sRIaAje&wr1>5r58NusobNL#T0OVm`;3alR!JOu&yfe3mbrNk5etl@`JN&V%wC!E zeMUv&uT&g-w~z;JEoIJ)T8hR-G#roVzNq&I@b<`JWtStkKODQ|mKqulS8(vXO&*TG z-c1~QZ<7Z`RpxweQ_+nw=R1gso*;9v)6m@GrrytF?#Q<@g}6H4tG76B3+QHwiQ5Aj zJK!P*u51yC`mil8a$u#5P~;yshUQy^;o*qmLjnkKG=}Co72$!%2?-#+-KspTieuuZ zZ(=jPjE5HF_|I3U9)*0iV8#b~RK-rve1BFQNinDqGwLgjq4$lU{~B~H-n->tLm%}U zn)=@ldUk|=05spzPdJ+|qkM$^ z2ka9dpg(qsBi_*R zfPuXYu$PKBwsmLEqM734UXW_Vt5)WftOD(^c{j&l|M-UeNbN z?7fNd;2+WakAZ$T!haC77-tE-=t}*MAZPr1lC+I@M1CY9|1{{w&^|Y?QvPMo&qnya z1#QNI{j0^q{4vIRr=GgDZU_#^W8JuhrwzXipM+-R#wf{&PU{ z`hpDdb>cz-y`C|C-UYfLLSF^?7Wi`;c(nIA&@B=EJ)ooU;E)EN^NjNMgFYGd@6z-a zKy$n~?HaM#egky=?Ur~7{igiWpyx&O{|>Z#eG6Fw=2HXWX-S07H#=5OwM0SJ=c{S! zBm8dAVSF`r%Kzmy;Y+>6GCrOw74XBSs$?_2cq)3<%f{rFeTjzTcYo0@?BMC`z0hB| zaqaTnZtUps;h+uJwt#y9zvt-qI-OHBy*h@7ZYG6%TZJRqp3*^L#2@*3+XqB|qfa#qYR^wDeKffZF$vD&uR!_z*54 zEh{(7_QxbvU z&lA~^Ts6wZy>AU;HIS|1Picg0ZfKxqct{3ccAzJV4#~YXnM%7Zh6 zl(NygY5Mtn+fjV(f=i!qhTmUFrwaX1RvM10s*!+Cv{>aRG0bH-`(P#`3I^+Ws6Sl2 z?%dGP_yn?aj`Ee9Dt<1VN)KkE4f|$sDHSm!+45}BFI_*%y1?D|3^a72^%6q{Ulks$ zs;^Sft~4Lpj`HOPU_w=livCJAdr?#dBbXoUw0^WUYV6TztdkfLQIa1hj#g**nW?UV zOa`~;uV(Y3!prx2*DTj_q@NRWlol>G3|xH48nY{yho_F5D*CZ5S4MR^V9&?a8Ga5q z8(1LPD!YfcZKe(VQu&}k(%X3dSnmB;x~v!!DQ-A47;Z9<#R#jAE~fMN+Iyg|T)^&B(trHHU){VP!!5Dkvyv)^6C%~g<8dNR z4=3gL4CQ7pT7b>LTQwf1;>7KUl;g7%ey5iAH!R~pIiCEw(Che)6ZP?#%OHSy=@tbz zj2!p&^2rG0_$=m~xL3OtI(aLDOv>^8cR5b5q#U2o@LS7L02vR;@;DbKzavF`e0IZo zvQA)QAIo`OfRo>yB9_l|(BM2moTgo}25_>eWjOh)hu_EKYi!gvQSG;+`4-tAfZ7=NxqS|LT*7LQACQjQ$n(?7Pz7QZn}lo_}`BFEpB z4==VwZ=_u#hg-rxAD=Nz#0MiDqp|uhavugwJLzjady1{YH&V0=GpZ(i7f${nrW~I^ zB*w^5hUWt~`Q(ane3nu77IF`PPje{8-^>k=dsUYqle+la;-7KS2Fl6bQuxSs^huJj z_3IHi-eXUP9LLBU#=d_=fzij`rdLCb<7y70k6)T#`)rrLIc|eo#LWSICL(vcmRo`{ zb5IA57jUxvJQ6slkH68(K_1VSaiYzVDZdwTJ%&JTY~V|l29upQ-xgOB=)<(j_b{V! z*Fvr`&Pav4X=CIZ-xi;iPFJ!<$J{Y;_x9N$ryg}mK_j<7%bEU8F4$rT7aV<1j_2Yr za+`;3F*TeXQigKtw4AOkN|)H;bCE|hl;Oc=RtA%v`yN~HD?H{fka?sT@$7qHA0FwR pi1M{K83zqG`II-}2GMezEw)DHk +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) + { // RISCV has no DIVI + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { // X * NPowerOf2 = X >> N (immediate shift left) + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSR_3(P0, P1, P2); + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include +#include +#include +#include "ReadPgmImage.h" + +typedef int (*pifc)(int[], int, int, int); + + +void printImage(imgStruct_t *img, char *imageName) +{ + printf ("ImageName & size: %s %dx%d\n", imageName, img->height, img->width); + for(int line = 0 ; line < img->height ; line++) + { + for(int column = 0 ; column < img->width ; column++) + { + printf("%03d ", img->pixelsArray[line*img->width+column]); + } + printf("\n"); + } + printf("\n"); +} + +int imgSum (imgStruct_t *img) +{ + int line, column, sum; + sum = 0; + for(int line = 0 ; line < img->height ; line++) + { + for(int column = 0 ; column < img->width; column++) + { + sum += img->pixelsArray[line*img->width+column]; + } + } + return (0 == sum)?1:sum; +} + +#if 0 +unsigned char clamp(int value) +{ + return (unsigned char)(0 > value)?0:(255 < value)?255:value; +} +#else +#define clamp(value) ((unsigned char)(0 > value)?0:(255 < value)?255:value) +#endif + +pifc genKernel1x1(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 13, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x3F3F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, line, imgWidth, immValueZero); + tmp0001 = riscv_genADD_3(tmp0001, tmp0000, column); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = riscv_genMUL_4(tmp0002, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = riscv_genADD_3(tmp0003, In, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = riscv_genR_3(tmp0004, tmp0003, immValueZero); + sum = riscv_genMUL_4(sum, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}, immValueZero); + if (!sum.dontFree) h2_freeReg(tmp0004.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0005 = riscv_genDIV_4(tmp0005, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}, immValueZero); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +pifc genKernel3x3(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 19 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 13, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 28, true}; + h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 29, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x30003FFF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + njp1 = riscv_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njm1 = riscv_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = riscv_genADD_3(tmp0000, stride, njm1); + tmp0001 = riscv_genMUL_4(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = riscv_genADD_3(tmp0002, In, tmp0001); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = riscv_genR_3(tmp0003, tmp0002, immValueZero); + sum = riscv_genMUL_4(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}, immValueZero); + if (!sum.dontFree) h2_freeReg(tmp0003.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0004 = riscv_genADD_3(tmp0004, stride, column); + tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = riscv_genADD_3(tmp0006, In, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = riscv_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = riscv_genMUL_4(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1]))}, immValueZero); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = riscv_genADD_3(sum, sum, tmp0008); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0009 = riscv_genADD_3(tmp0009, stride, njp1); + tmp0010 = riscv_genMUL_4(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = riscv_genADD_3(tmp0011, In, tmp0010); + if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); + tmp0012 = riscv_genR_3(tmp0012, tmp0011, immValueZero); + tmp0013 = riscv_genMUL_4(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2]))}, immValueZero); + if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); + sum = riscv_genADD_3(sum, sum, tmp0013); + if (!sum.dontFree) h2_freeReg(tmp0013.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genMV_2(ni, line); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0015 = riscv_genADD_3(tmp0015, stride, njm1); + tmp0016 = riscv_genMUL_4(tmp0016, tmp0015, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); + tmp0017 = riscv_genADD_3(tmp0017, In, tmp0016); + if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); + tmp0018 = riscv_genR_3(tmp0018, tmp0017, immValueZero); + tmp0019 = riscv_genMUL_4(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+0]))}, immValueZero); + if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); + sum = riscv_genADD_3(sum, sum, tmp0019); + if (!sum.dontFree) h2_freeReg(tmp0019.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0020 = riscv_genADD_3(tmp0020, stride, column); + tmp0021 = riscv_genMUL_4(tmp0021, tmp0020, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); + tmp0022 = riscv_genADD_3(tmp0022, In, tmp0021); + if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); + tmp0023 = riscv_genR_3(tmp0023, tmp0022, immValueZero); + tmp0024 = riscv_genMUL_4(tmp0024, tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+1]))}, immValueZero); + if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); + sum = riscv_genADD_3(sum, sum, tmp0024); + if (!sum.dontFree) h2_freeReg(tmp0024.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0025 = riscv_genADD_3(tmp0025, stride, njp1); + tmp0026 = riscv_genMUL_4(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = riscv_genADD_3(tmp0027, In, tmp0026); + if (!tmp0027.dontFree) h2_freeReg(tmp0026.regNro); + tmp0028 = riscv_genR_3(tmp0028, tmp0027, immValueZero); + tmp0029 = riscv_genMUL_4(tmp0029, tmp0028, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+2]))}, immValueZero); + if (!tmp0029.dontFree) h2_freeReg(tmp0028.regNro); + sum = riscv_genADD_3(sum, sum, tmp0029); + if (!sum.dontFree) h2_freeReg(tmp0029.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0030 = riscv_genADD_3(tmp0030, stride, njm1); + tmp0031 = riscv_genMUL_4(tmp0031, tmp0030, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = riscv_genADD_3(tmp0032, In, tmp0031); + if (!tmp0032.dontFree) h2_freeReg(tmp0031.regNro); + tmp0033 = riscv_genR_3(tmp0033, tmp0032, immValueZero); + tmp0034 = riscv_genMUL_4(tmp0034, tmp0033, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+0]))}, immValueZero); + if (!tmp0034.dontFree) h2_freeReg(tmp0033.regNro); + sum = riscv_genADD_3(sum, sum, tmp0034); + if (!sum.dontFree) h2_freeReg(tmp0034.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0035 = riscv_genADD_3(tmp0035, stride, column); + tmp0036 = riscv_genMUL_4(tmp0036, tmp0035, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = riscv_genADD_3(tmp0037, In, tmp0036); + if (!tmp0037.dontFree) h2_freeReg(tmp0036.regNro); + tmp0038 = riscv_genR_3(tmp0038, tmp0037, immValueZero); + tmp0039 = riscv_genMUL_4(tmp0039, tmp0038, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+1]))}, immValueZero); + if (!tmp0039.dontFree) h2_freeReg(tmp0038.regNro); + sum = riscv_genADD_3(sum, sum, tmp0039); + if (!sum.dontFree) h2_freeReg(tmp0039.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0040 = riscv_genADD_3(tmp0040, stride, njp1); + tmp0041 = riscv_genMUL_4(tmp0041, tmp0040, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + tmp0042 = riscv_genADD_3(tmp0042, In, tmp0041); + if (!tmp0042.dontFree) h2_freeReg(tmp0041.regNro); + tmp0043 = riscv_genR_3(tmp0043, tmp0042, immValueZero); + tmp0044 = riscv_genMUL_4(tmp0044, tmp0043, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+2]))}, immValueZero); + if (!tmp0044.dontFree) h2_freeReg(tmp0043.regNro); + sum = riscv_genADD_3(sum, sum, tmp0044); + if (!sum.dontFree) h2_freeReg(tmp0044.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0045 = riscv_genDIV_4(tmp0045, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}, immValueZero); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0045); + if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +pifc genKernel5x5(pifc ptr, int* Filter, int coeff) +{ + /* Code Generation of 41 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 12, true}; + h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 13, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t njm2 = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 28, true}; + h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 29, true}; + h2_sValue_t njp2 = {H2REGISTER, 'i', 1, 32, 30, true}; + h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 31, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0084 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0085 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0086 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0087 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0088 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0089 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0090 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0091 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0092 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0093 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0094 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0095 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0096 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0097 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0098 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0099 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0100 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0101 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0102 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0103 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0104 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0105 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0106 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0107 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0108 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0109 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0110 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0111 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0112 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0113 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0114 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0115 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0116 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0117 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0118 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0119 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0120 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0121 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0122 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0123 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0124 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0125 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0126 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF0003FFF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + njm2 = riscv_genSUB_3(njm2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njm1 = riscv_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njp1 = riscv_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + njp2 = riscv_genADD_3(njp2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0000 = riscv_genADD_3(tmp0000, stride, njm2); + tmp0001 = riscv_genMUL_4(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = riscv_genADD_3(tmp0002, In, tmp0001); + if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); + tmp0003 = riscv_genR_3(tmp0003, tmp0002, immValueZero); + sum = riscv_genMUL_4(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+0]))}, immValueZero); + if (!sum.dontFree) h2_freeReg(tmp0003.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0004 = riscv_genADD_3(tmp0004, stride, njm1); + tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = riscv_genADD_3(tmp0006, In, tmp0005); + if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); + tmp0007 = riscv_genR_3(tmp0007, tmp0006, immValueZero); + tmp0008 = riscv_genMUL_4(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+1]))}, immValueZero); + if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); + sum = riscv_genADD_3(sum, sum, tmp0008); + if (!sum.dontFree) h2_freeReg(tmp0008.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0009 = riscv_genADD_3(tmp0009, stride, column); + tmp0010 = riscv_genMUL_4(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = riscv_genADD_3(tmp0011, In, tmp0010); + if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); + tmp0012 = riscv_genR_3(tmp0012, tmp0011, immValueZero); + tmp0013 = riscv_genMUL_4(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+2]))}, immValueZero); + if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); + sum = riscv_genADD_3(sum, sum, tmp0013); + if (!sum.dontFree) h2_freeReg(tmp0013.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0014 = riscv_genADD_3(tmp0014, stride, njp1); + tmp0015 = riscv_genMUL_4(tmp0015, tmp0014, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); + tmp0016 = riscv_genADD_3(tmp0016, In, tmp0015); + if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); + tmp0017 = riscv_genR_3(tmp0017, tmp0016, immValueZero); + tmp0018 = riscv_genMUL_4(tmp0018, tmp0017, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+3]))}, immValueZero); + if (!tmp0018.dontFree) h2_freeReg(tmp0017.regNro); + sum = riscv_genADD_3(sum, sum, tmp0018); + if (!sum.dontFree) h2_freeReg(tmp0018.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0019 = riscv_genADD_3(tmp0019, stride, njp2); + tmp0020 = riscv_genMUL_4(tmp0020, tmp0019, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); + tmp0021 = riscv_genADD_3(tmp0021, In, tmp0020); + if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); + tmp0022 = riscv_genR_3(tmp0022, tmp0021, immValueZero); + tmp0023 = riscv_genMUL_4(tmp0023, tmp0022, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+4]))}, immValueZero); + if (!tmp0023.dontFree) h2_freeReg(tmp0022.regNro); + sum = riscv_genADD_3(sum, sum, tmp0023); + if (!sum.dontFree) h2_freeReg(tmp0023.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0024 = riscv_genADD_3(tmp0024, stride, njm2); + tmp0025 = riscv_genMUL_4(tmp0025, tmp0024, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0025.dontFree) h2_freeReg(tmp0024.regNro); + tmp0026 = riscv_genADD_3(tmp0026, In, tmp0025); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = riscv_genR_3(tmp0027, tmp0026, immValueZero); + tmp0028 = riscv_genMUL_4(tmp0028, tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+0]))}, immValueZero); + if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); + sum = riscv_genADD_3(sum, sum, tmp0028); + if (!sum.dontFree) h2_freeReg(tmp0028.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0029 = riscv_genADD_3(tmp0029, stride, njm1); + tmp0030 = riscv_genMUL_4(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); + tmp0031 = riscv_genADD_3(tmp0031, In, tmp0030); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = riscv_genR_3(tmp0032, tmp0031, immValueZero); + tmp0033 = riscv_genMUL_4(tmp0033, tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+1]))}, immValueZero); + if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); + sum = riscv_genADD_3(sum, sum, tmp0033); + if (!sum.dontFree) h2_freeReg(tmp0033.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0034 = riscv_genADD_3(tmp0034, stride, column); + tmp0035 = riscv_genMUL_4(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); + tmp0036 = riscv_genADD_3(tmp0036, In, tmp0035); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = riscv_genR_3(tmp0037, tmp0036, immValueZero); + tmp0038 = riscv_genMUL_4(tmp0038, tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+2]))}, immValueZero); + if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); + sum = riscv_genADD_3(sum, sum, tmp0038); + if (!sum.dontFree) h2_freeReg(tmp0038.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0039 = riscv_genADD_3(tmp0039, stride, njp1); + tmp0040 = riscv_genMUL_4(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); + tmp0041 = riscv_genADD_3(tmp0041, In, tmp0040); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + tmp0042 = riscv_genR_3(tmp0042, tmp0041, immValueZero); + tmp0043 = riscv_genMUL_4(tmp0043, tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+3]))}, immValueZero); + if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); + sum = riscv_genADD_3(sum, sum, tmp0043); + if (!sum.dontFree) h2_freeReg(tmp0043.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0044 = riscv_genADD_3(tmp0044, stride, njp2); + tmp0045 = riscv_genMUL_4(tmp0045, tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); + tmp0046 = riscv_genADD_3(tmp0046, In, tmp0045); + if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); + tmp0047 = riscv_genR_3(tmp0047, tmp0046, immValueZero); + tmp0048 = riscv_genMUL_4(tmp0048, tmp0047, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+4]))}, immValueZero); + if (!tmp0048.dontFree) h2_freeReg(tmp0047.regNro); + sum = riscv_genADD_3(sum, sum, tmp0048); + if (!sum.dontFree) h2_freeReg(tmp0048.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genMV_2(ni, line); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0050 = riscv_genADD_3(tmp0050, stride, njm2); + tmp0051 = riscv_genMUL_4(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); + tmp0052 = riscv_genADD_3(tmp0052, In, tmp0051); + if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); + tmp0053 = riscv_genR_3(tmp0053, tmp0052, immValueZero); + tmp0054 = riscv_genMUL_4(tmp0054, tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+0]))}, immValueZero); + if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); + sum = riscv_genADD_3(sum, sum, tmp0054); + if (!sum.dontFree) h2_freeReg(tmp0054.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0055 = riscv_genADD_3(tmp0055, stride, njm1); + tmp0056 = riscv_genMUL_4(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); + tmp0057 = riscv_genADD_3(tmp0057, In, tmp0056); + if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); + tmp0058 = riscv_genR_3(tmp0058, tmp0057, immValueZero); + tmp0059 = riscv_genMUL_4(tmp0059, tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+1]))}, immValueZero); + if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); + sum = riscv_genADD_3(sum, sum, tmp0059); + if (!sum.dontFree) h2_freeReg(tmp0059.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0060 = riscv_genADD_3(tmp0060, stride, column); + tmp0061 = riscv_genMUL_4(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); + tmp0062 = riscv_genADD_3(tmp0062, In, tmp0061); + if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); + tmp0063 = riscv_genR_3(tmp0063, tmp0062, immValueZero); + tmp0064 = riscv_genMUL_4(tmp0064, tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+2]))}, immValueZero); + if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); + sum = riscv_genADD_3(sum, sum, tmp0064); + if (!sum.dontFree) h2_freeReg(tmp0064.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0065 = riscv_genADD_3(tmp0065, stride, njp1); + tmp0066 = riscv_genMUL_4(tmp0066, tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); + tmp0067 = riscv_genADD_3(tmp0067, In, tmp0066); + if (!tmp0067.dontFree) h2_freeReg(tmp0066.regNro); + tmp0068 = riscv_genR_3(tmp0068, tmp0067, immValueZero); + tmp0069 = riscv_genMUL_4(tmp0069, tmp0068, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+3]))}, immValueZero); + if (!tmp0069.dontFree) h2_freeReg(tmp0068.regNro); + sum = riscv_genADD_3(sum, sum, tmp0069); + if (!sum.dontFree) h2_freeReg(tmp0069.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0070 = riscv_genADD_3(tmp0070, stride, njp2); + tmp0071 = riscv_genMUL_4(tmp0071, tmp0070, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0071.dontFree) h2_freeReg(tmp0070.regNro); + tmp0072 = riscv_genADD_3(tmp0072, In, tmp0071); + if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); + tmp0073 = riscv_genR_3(tmp0073, tmp0072, immValueZero); + tmp0074 = riscv_genMUL_4(tmp0074, tmp0073, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+4]))}, immValueZero); + if (!tmp0074.dontFree) h2_freeReg(tmp0073.regNro); + sum = riscv_genADD_3(sum, sum, tmp0074); + if (!sum.dontFree) h2_freeReg(tmp0074.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0075 = riscv_genADD_3(tmp0075, stride, njm2); + tmp0076 = riscv_genMUL_4(tmp0076, tmp0075, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0076.dontFree) h2_freeReg(tmp0075.regNro); + tmp0077 = riscv_genADD_3(tmp0077, In, tmp0076); + if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); + tmp0078 = riscv_genR_3(tmp0078, tmp0077, immValueZero); + tmp0079 = riscv_genMUL_4(tmp0079, tmp0078, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+0]))}, immValueZero); + if (!tmp0079.dontFree) h2_freeReg(tmp0078.regNro); + sum = riscv_genADD_3(sum, sum, tmp0079); + if (!sum.dontFree) h2_freeReg(tmp0079.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0080 = riscv_genADD_3(tmp0080, stride, njm1); + tmp0081 = riscv_genMUL_4(tmp0081, tmp0080, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0081.dontFree) h2_freeReg(tmp0080.regNro); + tmp0082 = riscv_genADD_3(tmp0082, In, tmp0081); + if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); + tmp0083 = riscv_genR_3(tmp0083, tmp0082, immValueZero); + tmp0084 = riscv_genMUL_4(tmp0084, tmp0083, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+1]))}, immValueZero); + if (!tmp0084.dontFree) h2_freeReg(tmp0083.regNro); + sum = riscv_genADD_3(sum, sum, tmp0084); + if (!sum.dontFree) h2_freeReg(tmp0084.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0085 = riscv_genADD_3(tmp0085, stride, column); + tmp0086 = riscv_genMUL_4(tmp0086, tmp0085, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0086.dontFree) h2_freeReg(tmp0085.regNro); + tmp0087 = riscv_genADD_3(tmp0087, In, tmp0086); + if (!tmp0087.dontFree) h2_freeReg(tmp0086.regNro); + tmp0088 = riscv_genR_3(tmp0088, tmp0087, immValueZero); + tmp0089 = riscv_genMUL_4(tmp0089, tmp0088, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+2]))}, immValueZero); + if (!tmp0089.dontFree) h2_freeReg(tmp0088.regNro); + sum = riscv_genADD_3(sum, sum, tmp0089); + if (!sum.dontFree) h2_freeReg(tmp0089.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0090 = riscv_genADD_3(tmp0090, stride, njp1); + tmp0091 = riscv_genMUL_4(tmp0091, tmp0090, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0091.dontFree) h2_freeReg(tmp0090.regNro); + tmp0092 = riscv_genADD_3(tmp0092, In, tmp0091); + if (!tmp0092.dontFree) h2_freeReg(tmp0091.regNro); + tmp0093 = riscv_genR_3(tmp0093, tmp0092, immValueZero); + tmp0094 = riscv_genMUL_4(tmp0094, tmp0093, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+3]))}, immValueZero); + if (!tmp0094.dontFree) h2_freeReg(tmp0093.regNro); + sum = riscv_genADD_3(sum, sum, tmp0094); + if (!sum.dontFree) h2_freeReg(tmp0094.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0095 = riscv_genADD_3(tmp0095, stride, njp2); + tmp0096 = riscv_genMUL_4(tmp0096, tmp0095, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0096.dontFree) h2_freeReg(tmp0095.regNro); + tmp0097 = riscv_genADD_3(tmp0097, In, tmp0096); + if (!tmp0097.dontFree) h2_freeReg(tmp0096.regNro); + tmp0098 = riscv_genR_3(tmp0098, tmp0097, immValueZero); + tmp0099 = riscv_genMUL_4(tmp0099, tmp0098, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+4]))}, immValueZero); + if (!tmp0099.dontFree) h2_freeReg(tmp0098.regNro); + sum = riscv_genADD_3(sum, sum, tmp0099); + if (!sum.dontFree) h2_freeReg(tmp0099.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + ni = riscv_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0100 = riscv_genADD_3(tmp0100, stride, njm2); + tmp0101 = riscv_genMUL_4(tmp0101, tmp0100, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0101.dontFree) h2_freeReg(tmp0100.regNro); + tmp0102 = riscv_genADD_3(tmp0102, In, tmp0101); + if (!tmp0102.dontFree) h2_freeReg(tmp0101.regNro); + tmp0103 = riscv_genR_3(tmp0103, tmp0102, immValueZero); + tmp0104 = riscv_genMUL_4(tmp0104, tmp0103, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+0]))}, immValueZero); + if (!tmp0104.dontFree) h2_freeReg(tmp0103.regNro); + sum = riscv_genADD_3(sum, sum, tmp0104); + if (!sum.dontFree) h2_freeReg(tmp0104.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0105 = riscv_genADD_3(tmp0105, stride, njm1); + tmp0106 = riscv_genMUL_4(tmp0106, tmp0105, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0106.dontFree) h2_freeReg(tmp0105.regNro); + tmp0107 = riscv_genADD_3(tmp0107, In, tmp0106); + if (!tmp0107.dontFree) h2_freeReg(tmp0106.regNro); + tmp0108 = riscv_genR_3(tmp0108, tmp0107, immValueZero); + tmp0109 = riscv_genMUL_4(tmp0109, tmp0108, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+1]))}, immValueZero); + if (!tmp0109.dontFree) h2_freeReg(tmp0108.regNro); + sum = riscv_genADD_3(sum, sum, tmp0109); + if (!sum.dontFree) h2_freeReg(tmp0109.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0110 = riscv_genADD_3(tmp0110, stride, column); + tmp0111 = riscv_genMUL_4(tmp0111, tmp0110, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0111.dontFree) h2_freeReg(tmp0110.regNro); + tmp0112 = riscv_genADD_3(tmp0112, In, tmp0111); + if (!tmp0112.dontFree) h2_freeReg(tmp0111.regNro); + tmp0113 = riscv_genR_3(tmp0113, tmp0112, immValueZero); + tmp0114 = riscv_genMUL_4(tmp0114, tmp0113, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+2]))}, immValueZero); + if (!tmp0114.dontFree) h2_freeReg(tmp0113.regNro); + sum = riscv_genADD_3(sum, sum, tmp0114); + if (!sum.dontFree) h2_freeReg(tmp0114.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0115 = riscv_genADD_3(tmp0115, stride, njp1); + tmp0116 = riscv_genMUL_4(tmp0116, tmp0115, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0116.dontFree) h2_freeReg(tmp0115.regNro); + tmp0117 = riscv_genADD_3(tmp0117, In, tmp0116); + if (!tmp0117.dontFree) h2_freeReg(tmp0116.regNro); + tmp0118 = riscv_genR_3(tmp0118, tmp0117, immValueZero); + tmp0119 = riscv_genMUL_4(tmp0119, tmp0118, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+3]))}, immValueZero); + if (!tmp0119.dontFree) h2_freeReg(tmp0118.regNro); + sum = riscv_genADD_3(sum, sum, tmp0119); + if (!sum.dontFree) h2_freeReg(tmp0119.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0120 = riscv_genADD_3(tmp0120, stride, njp2); + tmp0121 = riscv_genMUL_4(tmp0121, tmp0120, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + if (!tmp0121.dontFree) h2_freeReg(tmp0120.regNro); + tmp0122 = riscv_genADD_3(tmp0122, In, tmp0121); + if (!tmp0122.dontFree) h2_freeReg(tmp0121.regNro); + tmp0123 = riscv_genR_3(tmp0123, tmp0122, immValueZero); + tmp0124 = riscv_genMUL_4(tmp0124, tmp0123, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+4]))}, immValueZero); + if (!tmp0124.dontFree) h2_freeReg(tmp0123.regNro); + sum = riscv_genADD_3(sum, sum, tmp0124); + if (!sum.dontFree) h2_freeReg(tmp0124.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0125 = riscv_genDIV_4(tmp0125, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}, immValueZero); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0125); + if (!tmp0126.dontFree) h2_freeReg(tmp0125.regNro); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +#if 0 +#endif +} + +// Compute a stencil for 1 point +int kernelStatic(imgStruct_t *In, int l, int c, imgStruct_t *Filter, int coeff) +{ + int line, column, sum = 0; + int offset = (Filter->width)/2; + + for (line = 0; line < Filter->height; line++) + { + for (column = 0; column < Filter->width; column++) + { + int ni = (l + line) - offset; + int nj = (c + column) - offset; + sum += In->pixelsArray[ni*In->width+nj] * Filter->pixelsArray[line*Filter->width+column]; + } + } + return sum / coeff; +} + + +void convolutionStatic(imgStruct_t *In, imgStruct_t *Out, imgStruct_t *Filter, int coeff) +{ + int offset = Filter->width/2; + int result; + for (int line = offset; line < In->height - offset; line++) + { + for (int column = offset; column < In->width - offset; column++) + { + result = kernelStatic(In, line, column, Filter, coeff); + Out->pixelsArray[line*Out->width+column] = clamp(result); + } + } +} + +void convolutionH4(imgStruct_t* In, imgStruct_t *Out, imgStruct_t *Filter, pifc kernelHL) +{ + int offset = Filter->width/2; + int result; + for (int line = offset; line < In->height - offset; line++) + { + for (int column = offset; column < In->width - offset; column++) + { + result = kernelHL(In->pixelsArray, line, column, In->width); + Out->pixelsArray[line*Out->width+column] = clamp(result); + } + } +} + +int compareImages(imgStruct_t *staticImg, imgStruct_t *H4Img) +{ + int errors = 0; + for(int line = 0 ; line < staticImg->height ; line++) + { + for(int column = 0 ; column < staticImg->width ; column++) + { + if((staticImg->pixelsArray[line*staticImg->width+column] - H4Img->pixelsArray[line*H4Img->width+column]) != 0) + { + if (0 == errors) + { + printf("Alert : first difference at line %i column %i\n", line, column); + } + errors++; + } + } + } + return errors; +} + +int main(int argc, char *argv[]) +{ + int error, coeff, nXperiment = 20; + imgStruct_t *In, *OutH4, *OutStatic, *Filter; + char *filterImageName, *inputImageName; + if (argc < 5) + { + printf ("./Stencil \n"); + exit(-1); + } + + inputImageName = argv[1]; + filterImageName = argv[4]; + In = readPgmImage(inputImageName); + Filter = readPgmImage(filterImageName); + coeff = imgSum (Filter); +#ifdef VERBOSE + printf ("%s: coeff %d\n", filterImageName, coeff); + printImage (Filter, "Filter"); +#endif + assert (Filter->width == Filter->height); // Only square filters + OutStatic = createImage (In->height, In->width); + OutH4 = createImage (In->height, In->width); +#ifdef VERBOSE + printf ("after init\n"); + printImage(In, "In"); +#endif + ticks_t timeStatic = h2_getticks(); // Static convolution + for (int i = 0; i < nXperiment; i++) + { + convolutionStatic(In, OutStatic, Filter, coeff); + } + timeStatic = h2_getticks() - timeStatic; +#ifdef VERBOSE + printf ("after static\n"); + printImage(OutStatic, "Out"); +#endif + + pifc kernelHL = (pifc)h2_malloc(8192); + ticks_t timeCodeGen = h2_getticks(); + switch (Filter->width) + { + case 1 : kernelHL = genKernel1x1 (kernelHL, Filter->pixelsArray, coeff); break; + case 3 : kernelHL = genKernel3x3 (kernelHL, Filter->pixelsArray, coeff); break; + case 5 : kernelHL = genKernel5x5 (kernelHL, Filter->pixelsArray, coeff); break; + default: printf ("Unknown filter size\n"); exit(-1); + } + timeCodeGen = h2_getticks() - timeCodeGen; + +#ifdef VERBOSE + printf ("after codegen\n"); +#endif + + ticks_t timeH4 = h2_getticks(); // Compilette convolution + for (int i = 0; i < nXperiment; i++) + { + convolutionH4(In, OutH4, Filter, kernelHL); + } + timeH4 = h2_getticks() - timeH4; +#ifdef VERBOSE + printf ("after h2\n"); + printImage(OutH4, "Out H4"); +#endif + error = compareImages(OutH4, OutStatic); + printf("%s;%ix%i;%ix%i;%lld;%lld;%lld;%d;%d\n", + filterImageName, + Filter->width, Filter->height, In->width, In->height, + timeStatic/nXperiment, timeH4/nXperiment, + h2_codeGenTime, h2_insnGenerated, + error); + +#if VERBOSE + writePgmImage(OutStatic, argv[2]); + writePgmImage(OutH4, argv[3]); +#endif + + return (0 == error)?0:-1; +} diff --git a/Demos/VectorMatrix/VectorMatrix.aarch64 b/Demos/VectorMatrix/VectorMatrix.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..a5729cd05c96d172a4e5eae14fce4cb790f73491 GIT binary patch literal 63912 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +void A64_RET__I_64_1(){ /* ret */ + aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + +#ifdef H2_DEBUG_INSN +printf("%p : A64_RET__I_64_1\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_8_8(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_8_8\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_8_16(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_16_8(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_16_4(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_16_4\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_32_1(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_SUB_RRI_I_32_1(int r0,int r1,int i0){ /* sub */ + aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_32_2(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_32_2\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_32_4(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_64_2(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_64_2\n", h2_asm_pc); +#endif +} +void A64_SUB_RRI_I_64_1(int r0,int r1,int i0){ /* sub */ + aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void A64_SUB_RRR_I_64_1(int r0,int r1,int r2){ /* sub */ + aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_SUB_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_MOV_RRR_I_8_8(int r0,int r1,int r2){ /* mv */ + aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RRR_I_8_8\n", h2_asm_pc); +#endif +} +void A64_MOV_RRR_I_16_8(int r0,int r1,int r2){ /* mv */ + aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void A64_MV_RR_I_32_4(int r0,int r1){ /* mv */ + aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MV_RR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_MOV_RR_I_32_1(int r0,int r1){ /* mv */ + aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_MOVI_RI_I_32_4(int r0,int i0){ /* mv */ + aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOVI_RI_I_32_4\n", h2_asm_pc); +#endif +} +void A64_MOVI_RI_I_32_2(int r0,int i0){ /* mv */ + aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOVI_RI_I_32_2\n", h2_asm_pc); +#endif +} +void A64_DUP_RR_I_32_4(int r0,int r1){ /* mv */ + aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_DUP_RR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_MOV_RI_I_32_1(int r0,int i0){ /* mv */ + aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_MOV_RR_I_32_2(int r0,int r1){ /* mv */ + aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RR_I_32_2\n", h2_asm_pc); +#endif +} +void A64_DUP_RR_I_32_1(int r0,int r1){ /* mv */ + aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_DUP_RR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_DUP_RR_I_32_2(int r0,int r1){ /* mv */ + aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_DUP_RR_I_32_2\n", h2_asm_pc); +#endif +} +void A64_MOV_RR_I_64_1(int r0,int r1){ /* mv */ + aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_MOV_RI_I_64_1(int r0,int i0){ /* mv */ + aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MOV_RI_I_64_1\n", h2_asm_pc); +#endif +} +void A64_DUP_RR_I_64_1(int r0,int r1){ /* mv */ + aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_DUP_RR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_DUP_RR_I_64_2(int r0,int r1){ /* mv */ + aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_DUP_RR_I_64_2\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_8_8(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_8_8\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_8_16(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_16_4(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_16_4\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_16_8(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_32_4(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_32_1(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_32_2(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_32_2\n", h2_asm_pc); +#endif +} +void A64_MUL_RRR_I_64_1(int r0,int r1,int r2){ /* mul */ + aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_MUL_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_8_8(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_8_8\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_8_16(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_16_8(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_16_4(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_16_4\n", h2_asm_pc); +#endif +} +void A64_ADD_RRI_I_32_1(int r0,int r1,int i0){ /* add */ + aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_32_1(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_32_2(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_32_2\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_32_4(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_64_2(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_64_2\n", h2_asm_pc); +#endif +} +void A64_ADD_RRR_I_64_1(int r0,int r1,int r2){ /* add */ + aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_ADD_RRI_I_64_1(int r0,int r1,int i0){ /* add */ + aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ADD_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void A64_LSR_RRI_I_32_1(int r0,int r1,int i0){ /* sr */ + aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSR_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_LSR_RRR_I_32_1(int r0,int r1,int r2){ /* sr */ + aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSR_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_LSR_RRI_I_64_1(int r0,int r1,int i0){ /* sr */ + aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSR_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void A64_LSR_RRR_I_64_1(int r0,int r1,int r2){ /* sr */ + aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSR_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_ST1_RR_I_8_8(int r0,int r1){ /* w */ + aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ST1_RR_I_8_8\n", h2_asm_pc); +#endif +} +void A64_ST1_RR_I_8_16(int r0,int r1){ /* w */ + aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ST1_RR_I_8_16\n", h2_asm_pc); +#endif +} +void A64_STRB_RRI_I_8_1(int r0,int r1,int i0){ /* w */ + aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STRB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void A64_ST1_RR_I_16_8(int r0,int r1){ /* w */ + aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ST1_RR_I_16_8\n", h2_asm_pc); +#endif +} +void A64_ST1_RR_I_16_4(int r0,int r1){ /* w */ + aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ST1_RR_I_16_4\n", h2_asm_pc); +#endif +} +void A64_STRH_RRI_I_16_1(int r0,int r1,int i0){ /* w */ + aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STRH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void A64_STR_RRR_I_32_1(int r0,int r1,int r2){ /* w */ + aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STR_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_STR_RRI_I_32_1(int r0,int r1,int i0){ /* w */ + aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STR_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_STR_RRI_I_32_2(int r0,int r1,int i0){ /* w */ + aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STR_RRI_I_32_2\n", h2_asm_pc); +#endif +} +void A64_ST1_RR_I_32_4(int r0,int r1){ /* w */ + aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ST1_RR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_STR_RRR_I_64_1(int r0,int r1,int r2){ /* w */ + aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STR_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_ST1_RR_I_64_2(int r0,int r1){ /* w */ + aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_ST1_RR_I_64_2\n", h2_asm_pc); +#endif +} +void A64_STR_RRI_I_64_1(int r0,int r1,int i0){ /* w */ + aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_STR_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_8_16(int r0,int r1){ /* r */ + aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_8_16\n", h2_asm_pc); +#endif +} +void A64_LDRB_RRI_I_8_1(int r0,int r1,int i0){ /* r */ + aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LDRB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_8_8(int r0,int r1){ /* r */ + aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_8_8\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_16_4(int r0,int r1){ /* r */ + aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_16_4\n", h2_asm_pc); +#endif +} +void A64_LDRH_RRI_I_16_1(int r0,int r1,int i0){ /* r */ + aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LDRH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_16_8(int r0,int r1){ /* r */ + aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_16_8\n", h2_asm_pc); +#endif +} +void A64_LDR_RRI_I_32_1(int r0,int r1,int i0){ /* r */ + aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LDR_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_LDP_RRI_I_32_2(int r0,int r1,int i0){ /* r */ + aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LDP_RRI_I_32_2\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_32_2(int r0,int r1){ /* r */ + aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_32_2\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_32_4(int r0,int r1){ /* r */ + aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_32_4\n", h2_asm_pc); +#endif +} +void A64_LDR_RRR_I_64_1(int r0,int r1,int r2){ /* r */ + aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LDR_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void A64_LD1_RR_I_64_2(int r0,int r1){ /* r */ + aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LD1_RR_I_64_2\n", h2_asm_pc); +#endif +} +void A64_LSL_RRI_I_32_1(int r0,int r1,int i0){ /* sl */ + aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSL_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void A64_LSL_RRR_I_32_1(int r0,int r1,int r2){ /* sl */ + aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void A64_LSL_RRI_I_64_1(int r0,int r1,int i0){ /* sl */ + aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSL_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void A64_LSL_RRR_I_64_1(int r0,int r1,int r2){ /* sl */ + aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : A64_LSL_RRR_I_64_1\n", h2_asm_pc); +#endif +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +/* -*- c -*- */ +// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/mesa/math/m_matrix.c +#include +#include +#include +#include +#define T 4 +typedef int d_t; +typedef d_t matrix_t [T][T]; +typedef d_t vector_t [T]; +typedef d_t (*pifvv)(vector_t, vector_t); + +pifvv genVectorMatrixProduct(pifvv ptr, matrix_t m) +{ + /* Code Generation of 5 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t o = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0103, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = aarch64_genMUL_3(tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0001 = aarch64_genADD_3(tmp0001, o, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = aarch64_genMUL_3(tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0003 = aarch64_genADD_3(tmp0003, i, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = aarch64_genR_3(tmp0004, tmp0003, immValueZero); + tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][0]))}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = aarch64_genMUL_3(tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0007 = aarch64_genADD_3(tmp0007, i, tmp0006); + if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); + tmp0008 = aarch64_genR_3(tmp0008, tmp0007, immValueZero); + tmp0009 = aarch64_genMUL_3(tmp0009, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][0]))}); + if (!tmp0009.dontFree) h2_freeReg(tmp0008.regNro); + tmp0010 = aarch64_genADD_3(tmp0010, tmp0005, tmp0009); + if (!tmp0010.dontFree) h2_freeReg(tmp0005.regNro); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = aarch64_genMUL_3(tmp0011, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0012 = aarch64_genADD_3(tmp0012, i, tmp0011); + if (!tmp0012.dontFree) h2_freeReg(tmp0011.regNro); + tmp0013 = aarch64_genR_3(tmp0013, tmp0012, immValueZero); + tmp0014 = aarch64_genMUL_3(tmp0014, tmp0013, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][0]))}); + if (!tmp0014.dontFree) h2_freeReg(tmp0013.regNro); + tmp0015 = aarch64_genADD_3(tmp0015, tmp0010, tmp0014); + if (!tmp0015.dontFree) h2_freeReg(tmp0010.regNro); + if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); + tmp0016 = aarch64_genMUL_3(tmp0016, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0017 = aarch64_genADD_3(tmp0017, i, tmp0016); + if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); + tmp0018 = aarch64_genR_3(tmp0018, tmp0017, immValueZero); + tmp0019 = aarch64_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][0]))}); + if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); + tmp0020 = aarch64_genADD_3(tmp0020, tmp0015, tmp0019); + if (!tmp0020.dontFree) h2_freeReg(tmp0015.regNro); + if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); + aarch64_genW_3(tmp0001, tmp0020, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0021 = aarch64_genMUL_3(tmp0021, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0022 = aarch64_genADD_3(tmp0022, o, tmp0021); + if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); + tmp0023 = aarch64_genMUL_3(tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0024 = aarch64_genADD_3(tmp0024, i, tmp0023); + if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); + tmp0025 = aarch64_genR_3(tmp0025, tmp0024, immValueZero); + tmp0026 = aarch64_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][1]))}); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = aarch64_genMUL_3(tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0028 = aarch64_genADD_3(tmp0028, i, tmp0027); + if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); + tmp0029 = aarch64_genR_3(tmp0029, tmp0028, immValueZero); + tmp0030 = aarch64_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][1]))}); + if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); + tmp0031 = aarch64_genADD_3(tmp0031, tmp0026, tmp0030); + if (!tmp0031.dontFree) h2_freeReg(tmp0026.regNro); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = aarch64_genMUL_3(tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0033 = aarch64_genADD_3(tmp0033, i, tmp0032); + if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); + tmp0034 = aarch64_genR_3(tmp0034, tmp0033, immValueZero); + tmp0035 = aarch64_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][1]))}); + if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); + tmp0036 = aarch64_genADD_3(tmp0036, tmp0031, tmp0035); + if (!tmp0036.dontFree) h2_freeReg(tmp0031.regNro); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = aarch64_genMUL_3(tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0038 = aarch64_genADD_3(tmp0038, i, tmp0037); + if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); + tmp0039 = aarch64_genR_3(tmp0039, tmp0038, immValueZero); + tmp0040 = aarch64_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][1]))}); + if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); + tmp0041 = aarch64_genADD_3(tmp0041, tmp0036, tmp0040); + if (!tmp0041.dontFree) h2_freeReg(tmp0036.regNro); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + aarch64_genW_3(tmp0022, tmp0041, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0042 = aarch64_genMUL_3(tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0043 = aarch64_genADD_3(tmp0043, o, tmp0042); + if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); + tmp0044 = aarch64_genMUL_3(tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0045 = aarch64_genADD_3(tmp0045, i, tmp0044); + if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); + tmp0046 = aarch64_genR_3(tmp0046, tmp0045, immValueZero); + tmp0047 = aarch64_genMUL_3(tmp0047, tmp0046, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][2]))}); + if (!tmp0047.dontFree) h2_freeReg(tmp0046.regNro); + tmp0048 = aarch64_genMUL_3(tmp0048, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0049 = aarch64_genADD_3(tmp0049, i, tmp0048); + if (!tmp0049.dontFree) h2_freeReg(tmp0048.regNro); + tmp0050 = aarch64_genR_3(tmp0050, tmp0049, immValueZero); + tmp0051 = aarch64_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][2]))}); + if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); + tmp0052 = aarch64_genADD_3(tmp0052, tmp0047, tmp0051); + if (!tmp0052.dontFree) h2_freeReg(tmp0047.regNro); + if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); + tmp0053 = aarch64_genMUL_3(tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0054 = aarch64_genADD_3(tmp0054, i, tmp0053); + if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); + tmp0055 = aarch64_genR_3(tmp0055, tmp0054, immValueZero); + tmp0056 = aarch64_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][2]))}); + if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); + tmp0057 = aarch64_genADD_3(tmp0057, tmp0052, tmp0056); + if (!tmp0057.dontFree) h2_freeReg(tmp0052.regNro); + if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); + tmp0058 = aarch64_genMUL_3(tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0059 = aarch64_genADD_3(tmp0059, i, tmp0058); + if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); + tmp0060 = aarch64_genR_3(tmp0060, tmp0059, immValueZero); + tmp0061 = aarch64_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][2]))}); + if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); + tmp0062 = aarch64_genADD_3(tmp0062, tmp0057, tmp0061); + if (!tmp0062.dontFree) h2_freeReg(tmp0057.regNro); + if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); + aarch64_genW_3(tmp0043, tmp0062, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0063 = aarch64_genMUL_3(tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0064 = aarch64_genADD_3(tmp0064, o, tmp0063); + if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); + tmp0065 = aarch64_genMUL_3(tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0066 = aarch64_genADD_3(tmp0066, i, tmp0065); + if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); + tmp0067 = aarch64_genR_3(tmp0067, tmp0066, immValueZero); + tmp0068 = aarch64_genMUL_3(tmp0068, tmp0067, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][3]))}); + if (!tmp0068.dontFree) h2_freeReg(tmp0067.regNro); + tmp0069 = aarch64_genMUL_3(tmp0069, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0070 = aarch64_genADD_3(tmp0070, i, tmp0069); + if (!tmp0070.dontFree) h2_freeReg(tmp0069.regNro); + tmp0071 = aarch64_genR_3(tmp0071, tmp0070, immValueZero); + tmp0072 = aarch64_genMUL_3(tmp0072, tmp0071, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][3]))}); + if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); + tmp0073 = aarch64_genADD_3(tmp0073, tmp0068, tmp0072); + if (!tmp0073.dontFree) h2_freeReg(tmp0068.regNro); + if (!tmp0073.dontFree) h2_freeReg(tmp0072.regNro); + tmp0074 = aarch64_genMUL_3(tmp0074, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0075 = aarch64_genADD_3(tmp0075, i, tmp0074); + if (!tmp0075.dontFree) h2_freeReg(tmp0074.regNro); + tmp0076 = aarch64_genR_3(tmp0076, tmp0075, immValueZero); + tmp0077 = aarch64_genMUL_3(tmp0077, tmp0076, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][3]))}); + if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); + tmp0078 = aarch64_genADD_3(tmp0078, tmp0073, tmp0077); + if (!tmp0078.dontFree) h2_freeReg(tmp0073.regNro); + if (!tmp0078.dontFree) h2_freeReg(tmp0077.regNro); + tmp0079 = aarch64_genMUL_3(tmp0079, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0080 = aarch64_genADD_3(tmp0080, i, tmp0079); + if (!tmp0080.dontFree) h2_freeReg(tmp0079.regNro); + tmp0081 = aarch64_genR_3(tmp0081, tmp0080, immValueZero); + tmp0082 = aarch64_genMUL_3(tmp0082, tmp0081, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][3]))}); + if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); + tmp0083 = aarch64_genADD_3(tmp0083, tmp0078, tmp0082); + if (!tmp0083.dontFree) h2_freeReg(tmp0078.regNro); + if (!tmp0083.dontFree) h2_freeReg(tmp0082.regNro); + aarch64_genW_3(tmp0064, tmp0083, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +d_t VectorMatrixProductUnrolled (vector_t o, vector_t i, matrix_t m) +{ + o[0] = i[0]*m[0][0] + i[1]*m[1][0] + i[2]*m[2][0] + i[3]*m[3][0]; + o[1] = i[0]*m[0][1] + i[1]*m[1][1] + i[2]*m[2][1] + i[3]*m[3][1]; + o[2] = i[0]*m[0][2] + i[1]*m[1][2] + i[2]*m[2][2] + i[3]*m[3][2]; + o[3] = i[0]*m[0][3] + i[1]*m[1][3] + i[2]*m[2][3] + i[3]*m[3][3]; + return o[3]; +} + +#if 0 // What the binary code should be with a translation matrix +d_t VectorMatrixProductUnrolledSR(vector_t o, vector_t i, matrix_t m) +{ + + o[0] = m[0][0] * i[0] + + m[3][0] * i[3]; + o[1] = m[1][1] * i[1] + + m[3][1] * i[3]; + o[2] = m[2][2] * i[2] + m[3][2] * i[3]; + o[3] = + i[3]; + return o[3]; +} +#endif +d_t VectorMatrixProduct (vector_t o, vector_t i, matrix_t m) +{ + for (int column = 0; column < T; column++) + { + o[column] = 0; + for (int line = 0; line < T; line++) + { + o[column] += i[line] * m[line][column]; + + } + } + return o[3]; +} + + +int VectorMatrixProductCount(matrix_t mat) +{ + int op = 0; + for (int column = 0; column < T; column++) + { + for (int line = 0; line < T; line++) + { + switch (mat[line][column]) + { + case 0 : op += 0; break; + case 1 : op += 1; break; + default: op += 2; break; + } + } + } + return op; +} + + +void printMatrix (matrix_t m, char msg[]) +{ + printf ("%s:\n", msg); + for (int column = 0; column < T; column++) + { + for (int line = 0; line < T; line++) + { + printf ("%4d ", m[line][column]); + } + printf ("\n"); + } + printf ("\n"); +} + +void printVector (vector_t v, char msg[]) +{ + for (int i = 0; i < T; i++) + printf ("%4d ", v[i]); + printf ("%s\n", msg); +} + +bool vectorCompare(vector_t ref[], vector_t other[], char * msg, int doPrint, int nVector) +{ + int has_differences = false; + for (int line = 0; line < nVector; line++) + for (int i = 0; i < T; i++) + { + if (ref[line][i] != other[line][i]) + has_differences = true; + if (doPrint) + printf("%4d ", other[line][i]); + } + /* printf("%s : ", msg); */ + /* printf(" %s\n", (has_differences)?"NOT OK":"OK"); */ + return has_differences; +} + +int main (int argc, char *argv[]) +{ + matrix_t m; + char *matrixName; + // vector_t in0 = {1, 2, 3, 4}, in1 = {5, 6, 7, 8}; + vector_t *out, *cout, *in; + uint64_t timeGeneral, timeCompilette; + pifvv vmProduct; + int tmp, doPrint, nXperiment; + unsigned long acc; + bool resultValid; + + if (argc != 19) + { + printf ("Not enough arguments %d\n", argc); + printf ("VectorMatrix ExperimentNumber MatrixName M11 M12 ... M44\n"); + exit (-1); + } + doPrint = 0; + acc = 0; + nXperiment = atoi (argv[1]); + matrixName = argv[2]; + for (int line = 0; line < 4; line++) + for (int column = 0; column < 4; column++) + { + m[line][column] = atoi (argv[3 + line*4+column]); + } +#ifdef VERBOSE + printMatrix(m, matrixName); +#endif + + in = calloc(nXperiment, sizeof (vector_t)); + out = calloc(nXperiment, sizeof (vector_t)); + cout = calloc(nXperiment, sizeof (vector_t)); + + for (int line = 0; line < nXperiment; line++) + for (int column = 0; column < 4; column++) + in[line][column] = random () % 1000; + + tmp = VectorMatrixProductCount (m); + printf("Operation count Matrix %s : %d theoretical speedup %.1f\n", matrixName, tmp, (0==tmp)?32:32.0/tmp); + +// Repeat one instruction and count ticks +#define DO(INSN, REPEAT, TIME) {uint64_t tickCount = h2_getticks();for (int i = 0; i < REPEAT; i++) INSN; TIME = h2_getticks() - tickCount;} + +#ifdef VERBOSE + printVector (in[0], "Input vector #0"); +#endif + + acc += VectorMatrixProduct (out[0], in[0], m); /* Cold start */ + DO(acc += VectorMatrixProduct (out[i], in[i], m), nXperiment, timeGeneral) + +#ifdef VERBOSE + printVector (out[0], "Output vector #0 (general)"); +#endif + +#if 0 // Possible test with a source level unrolled version + uint64_t timeUnrolled; + vector_t uout0, uout1; + acc += VectorMatrixProductUnrolled (uout0, in0, m); + DO(acc += VectorMatrixProductUnrolled (uout1, in1, m), nXperiment, timeUnrolled); + vectorCompare(out1, uout1, "Unrolled out0", doPrint); +#endif + + vmProduct = (pifvv) h2_malloc(1024); + vmProduct = genVectorMatrixProduct (vmProduct, m); + acc += vmProduct (cout[0], in[0]); + DO(acc += vmProduct (cout[i], in[i]), nXperiment, timeCompilette); + +#ifdef VERBOSE + printVector (cout[0], "Output vector #0 (compilette)"); +#endif + + resultValid = vectorCompare(out, cout, "Compilette", doPrint, nXperiment); + + printf ("%s;%d;%lu;%lu;%lld;%d;%s\n", + matrixName, nXperiment, + timeGeneral, timeCompilette, + h2_codeGenTime, h2_insnGenerated, + resultValid?"true":"false"); + return resultValid; +} diff --git a/Demos/VectorMatrix/VectorMatrix.power b/Demos/VectorMatrix/VectorMatrix.power new file mode 100755 index 0000000000000000000000000000000000000000..3cf332b703c4aebb261c30c4221ad8674f510874 GIT binary patch literal 80624 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 XKfZptzwnlb`R^@Q%BvoO*9`szd0{3w literal 0 HcmV?d00001 diff --git a/Demos/VectorMatrix/VectorMatrix.power.c b/Demos/VectorMatrix/VectorMatrix.power.c new file mode 100644 index 0000000..ef2ed96 --- /dev/null +++ b/Demos/VectorMatrix/VectorMatrix.power.c @@ -0,0 +1,1457 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +void P1_BLR__I_32_1(){ /* ret */ + power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + +#ifdef H2_DEBUG_INSN +printf("%p : P1_BLR__I_32_1\n", h2_asm_pc); +#endif +} +void P1_SUBI_RRI_I_32_1(int r0,int r1,int i0){ /* sub */ + power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_SUBI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void PPC_SUB_RRR_I_32_1(int r0,int r2,int r1){ /* sub */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : PPC_SUB_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void P1_LI_RI_I_32_1(int r0,int i0){ /* mv */ + power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LI_RI_I_32_1\n", h2_asm_pc); +#endif +} +void P1_MV_RR_I_32_1(int r0,int r1){ /* mv */ + power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_MV_RR_I_32_1\n", h2_asm_pc); +#endif +} +void P1_LI_RI_I_64_1(int r0,int i0){ /* mv */ + power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LI_RI_I_64_1\n", h2_asm_pc); +#endif +} +void V2_03_VSRB_RRR_I_8_16(int r0,int r1,int r2){ /* sr */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSRB_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void V2_03_VSRH_RRR_I_16_8(int r0,int r1,int r2){ /* sr */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSRH_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void V2_03_VSRW_RRR_I_32_4(int r0,int r1,int r2){ /* sr */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSRW_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void V2_07_VSRD_RRR_I_64_2(int r0,int r1,int r2){ /* sr */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_07_VSRD_RRR_I_64_2\n", h2_asm_pc); +#endif +} +void V2_03_VSR_RRR_I_128_1(int r0,int r1,int r2){ /* sr */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSR_RRR_I_128_1\n", h2_asm_pc); +#endif +} +void P1_MULLW_RRR_I_32_1(int r0,int r1,int r2){ /* mul */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_MULLW_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void P1_MULLI_RRI_I_64_1(int r0,int r1,int i0){ /* mul */ + power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_MULLI_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void V2_03_VADDSBS_RRR_I_8_16(int r0,int r1,int r2){ /* add */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VADDSBS_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void V2_03_VADDUBS_RRR_I_8_16(int r0,int r1,int r2){ /* add */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VADDUBS_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void V2_03_VADDSHS_RRR_I_16_8(int r0,int r1,int r2){ /* add */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VADDSHS_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void V2_03_VADDUHS_RRR_I_16_8(int r0,int r1,int r2){ /* add */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VADDUHS_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void V2_03_VADDUWS_RRR_I_32_4(int r0,int r1,int r2){ /* add */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VADDUWS_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void P1_ADDI_RRI_I_32_1(int r0,int r1,int i0){ /* add */ + power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_ADDI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void V2_03_VADDSWS_RRR_I_32_4(int r0,int r1,int r2){ /* add */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VADDSWS_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void P1_ADD_RRR_I_32_1(int r0,int r1,int r2){ /* add */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_ADD_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void P1_ADD_RRR_I_64_1(int r0,int r1,int r2){ /* add */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_ADD_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void P1_ADDI_RRI_I_64_1(int r0,int r1,int i0){ /* add */ + power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_ADDI_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void P1_STB_RRI_I_8_1(int r1,int r0,int i0){ /* w */ + power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_STB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void P1_STBX_RRR_I_8_1(int r1,int r0,int r2){ /* w */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_STBX_RRR_I_8_1\n", h2_asm_pc); +#endif +} +void P1_STH_RRI_I_16_1(int r1,int r0,int i0){ /* w */ + power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_STH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void P1_STW_RRI_I_32_1(int r1,int r0,int i0){ /* w */ + power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_STW_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void P1_STWX_RRR_I_32_1(int r0,int r1,int r2){ /* w */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_STWX_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void PPC_STD_RRI_I_64_1(int r1,int r0,int i0){ /* w */ + power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : PPC_STD_RRI_I_64_1\n", h2_asm_pc); +#endif +} +void P1_LBZ_RRI_I_8_1(int r0,int r1,int i0){ /* r */ + power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LBZ_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void P1_LBZX_RRR_I_8_1(int r0,int r1,int r2){ /* r */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LBZX_RRR_I_8_1\n", h2_asm_pc); +#endif +} +void P1_LHZ_RRI_I_16_1(int r0,int r1,int i0){ /* r */ + power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LHZ_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void P1_LWZ_RRI_I_32_1(int r0,int r1,int i0){ /* r */ + power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LWZ_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void P1_LWZU_RRI_I_32_1(int r0,int r1,int i0){ /* r */ + power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LWZU_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void P1_LWZUX_RRR_I_32_1(int r0,int r1,int r2){ /* r */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LWZUX_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void P1_LWZX_RRR_I_32_1(int r0,int r1,int r2){ /* r */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_LWZX_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void V2_03_VSLB_RRR_I_8_16(int r0,int r1,int r2){ /* sl */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSLB_RRR_I_8_16\n", h2_asm_pc); +#endif +} +void V2_03_VSLH_RRR_I_16_8(int r0,int r1,int r2){ /* sl */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSLH_RRR_I_16_8\n", h2_asm_pc); +#endif +} +void P1_SLW_RRR_I_32_1(int r1,int r0,int r2){ /* sl */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_SLW_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void P1_SLW__RRR_I_32_1(int r1,int r0,int r2){ /* sl */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : P1_SLW__RRR_I_32_1\n", h2_asm_pc); +#endif +} +void V2_03_VSLW_RRR_I_32_4(int r0,int r1,int r2){ /* sl */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSLW_RRR_I_32_4\n", h2_asm_pc); +#endif +} +void PPC_SLD_RRR_I_64_1(int r1,int r0,int r2){ /* sl */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : PPC_SLD_RRR_I_64_1\n", h2_asm_pc); +#endif +} +void PPC_SLD__RRR_I_64_1(int r1,int r0,int r2){ /* sl */ + power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : PPC_SLD__RRR_I_64_1\n", h2_asm_pc); +#endif +} +void V2_07_VSLD_RRR_I_64_2(int r0,int r1,int r2){ /* sl */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_07_VSLD_RRR_I_64_2\n", h2_asm_pc); +#endif +} +void V2_03_VSL_RRR_I_128_1(int r0,int r1,int r2){ /* sl */ + power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : V2_03_VSL_RRR_I_128_1\n", h2_asm_pc); +#endif +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} + +/* End Header autogenerated part */ +/* -*- c -*- */ +// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/mesa/math/m_matrix.c +#include +#include +#include +#include +#define T 4 +typedef int d_t; +typedef d_t matrix_t [T][T]; +typedef d_t vector_t [T]; +typedef d_t (*pifvv)(vector_t, vector_t); + +pifvv genVectorMatrixProduct(pifvv ptr, matrix_t m) +{ + /* Code Generation of 5 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t o = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 4, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 64, -1, false}; + h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x381F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp0000 = power_genMUL_3(tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0001 = power_genADD_3(tmp0001, o, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = power_genMUL_3(tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0003 = power_genADD_3(tmp0003, i, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = power_genR_3(tmp0004, tmp0003, immValueZero); + tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][0]))}); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = power_genMUL_3(tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0007 = power_genADD_3(tmp0007, i, tmp0006); + if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); + tmp0008 = power_genR_3(tmp0008, tmp0007, immValueZero); + tmp0009 = power_genMUL_3(tmp0009, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][0]))}); + if (!tmp0009.dontFree) h2_freeReg(tmp0008.regNro); + tmp0010 = power_genADD_3(tmp0010, tmp0005, tmp0009); + if (!tmp0010.dontFree) h2_freeReg(tmp0005.regNro); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = power_genMUL_3(tmp0011, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0012 = power_genADD_3(tmp0012, i, tmp0011); + if (!tmp0012.dontFree) h2_freeReg(tmp0011.regNro); + tmp0013 = power_genR_3(tmp0013, tmp0012, immValueZero); + tmp0014 = power_genMUL_3(tmp0014, tmp0013, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][0]))}); + if (!tmp0014.dontFree) h2_freeReg(tmp0013.regNro); + tmp0015 = power_genADD_3(tmp0015, tmp0010, tmp0014); + if (!tmp0015.dontFree) h2_freeReg(tmp0010.regNro); + if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); + tmp0016 = power_genMUL_3(tmp0016, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0017 = power_genADD_3(tmp0017, i, tmp0016); + if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); + tmp0018 = power_genR_3(tmp0018, tmp0017, immValueZero); + tmp0019 = power_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][0]))}); + if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); + tmp0020 = power_genADD_3(tmp0020, tmp0015, tmp0019); + if (!tmp0020.dontFree) h2_freeReg(tmp0015.regNro); + if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); + power_genW_3(tmp0001, tmp0020, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0021 = power_genMUL_3(tmp0021, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0022 = power_genADD_3(tmp0022, o, tmp0021); + if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); + tmp0023 = power_genMUL_3(tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0024 = power_genADD_3(tmp0024, i, tmp0023); + if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); + tmp0025 = power_genR_3(tmp0025, tmp0024, immValueZero); + tmp0026 = power_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][1]))}); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = power_genMUL_3(tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0028 = power_genADD_3(tmp0028, i, tmp0027); + if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); + tmp0029 = power_genR_3(tmp0029, tmp0028, immValueZero); + tmp0030 = power_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][1]))}); + if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); + tmp0031 = power_genADD_3(tmp0031, tmp0026, tmp0030); + if (!tmp0031.dontFree) h2_freeReg(tmp0026.regNro); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = power_genMUL_3(tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0033 = power_genADD_3(tmp0033, i, tmp0032); + if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); + tmp0034 = power_genR_3(tmp0034, tmp0033, immValueZero); + tmp0035 = power_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][1]))}); + if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); + tmp0036 = power_genADD_3(tmp0036, tmp0031, tmp0035); + if (!tmp0036.dontFree) h2_freeReg(tmp0031.regNro); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = power_genMUL_3(tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0038 = power_genADD_3(tmp0038, i, tmp0037); + if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); + tmp0039 = power_genR_3(tmp0039, tmp0038, immValueZero); + tmp0040 = power_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][1]))}); + if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); + tmp0041 = power_genADD_3(tmp0041, tmp0036, tmp0040); + if (!tmp0041.dontFree) h2_freeReg(tmp0036.regNro); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + power_genW_3(tmp0022, tmp0041, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0042 = power_genMUL_3(tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0043 = power_genADD_3(tmp0043, o, tmp0042); + if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); + tmp0044 = power_genMUL_3(tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0045 = power_genADD_3(tmp0045, i, tmp0044); + if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); + tmp0046 = power_genR_3(tmp0046, tmp0045, immValueZero); + tmp0047 = power_genMUL_3(tmp0047, tmp0046, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][2]))}); + if (!tmp0047.dontFree) h2_freeReg(tmp0046.regNro); + tmp0048 = power_genMUL_3(tmp0048, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0049 = power_genADD_3(tmp0049, i, tmp0048); + if (!tmp0049.dontFree) h2_freeReg(tmp0048.regNro); + tmp0050 = power_genR_3(tmp0050, tmp0049, immValueZero); + tmp0051 = power_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][2]))}); + if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); + tmp0052 = power_genADD_3(tmp0052, tmp0047, tmp0051); + if (!tmp0052.dontFree) h2_freeReg(tmp0047.regNro); + if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); + tmp0053 = power_genMUL_3(tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0054 = power_genADD_3(tmp0054, i, tmp0053); + if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); + tmp0055 = power_genR_3(tmp0055, tmp0054, immValueZero); + tmp0056 = power_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][2]))}); + if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); + tmp0057 = power_genADD_3(tmp0057, tmp0052, tmp0056); + if (!tmp0057.dontFree) h2_freeReg(tmp0052.regNro); + if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); + tmp0058 = power_genMUL_3(tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0059 = power_genADD_3(tmp0059, i, tmp0058); + if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); + tmp0060 = power_genR_3(tmp0060, tmp0059, immValueZero); + tmp0061 = power_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][2]))}); + if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); + tmp0062 = power_genADD_3(tmp0062, tmp0057, tmp0061); + if (!tmp0062.dontFree) h2_freeReg(tmp0057.regNro); + if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); + power_genW_3(tmp0043, tmp0062, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0063 = power_genMUL_3(tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0064 = power_genADD_3(tmp0064, o, tmp0063); + if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); + tmp0065 = power_genMUL_3(tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0066 = power_genADD_3(tmp0066, i, tmp0065); + if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); + tmp0067 = power_genR_3(tmp0067, tmp0066, immValueZero); + tmp0068 = power_genMUL_3(tmp0068, tmp0067, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][3]))}); + if (!tmp0068.dontFree) h2_freeReg(tmp0067.regNro); + tmp0069 = power_genMUL_3(tmp0069, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0070 = power_genADD_3(tmp0070, i, tmp0069); + if (!tmp0070.dontFree) h2_freeReg(tmp0069.regNro); + tmp0071 = power_genR_3(tmp0071, tmp0070, immValueZero); + tmp0072 = power_genMUL_3(tmp0072, tmp0071, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][3]))}); + if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); + tmp0073 = power_genADD_3(tmp0073, tmp0068, tmp0072); + if (!tmp0073.dontFree) h2_freeReg(tmp0068.regNro); + if (!tmp0073.dontFree) h2_freeReg(tmp0072.regNro); + tmp0074 = power_genMUL_3(tmp0074, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0075 = power_genADD_3(tmp0075, i, tmp0074); + if (!tmp0075.dontFree) h2_freeReg(tmp0074.regNro); + tmp0076 = power_genR_3(tmp0076, tmp0075, immValueZero); + tmp0077 = power_genMUL_3(tmp0077, tmp0076, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][3]))}); + if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); + tmp0078 = power_genADD_3(tmp0078, tmp0073, tmp0077); + if (!tmp0078.dontFree) h2_freeReg(tmp0073.regNro); + if (!tmp0078.dontFree) h2_freeReg(tmp0077.regNro); + tmp0079 = power_genMUL_3(tmp0079, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); + tmp0080 = power_genADD_3(tmp0080, i, tmp0079); + if (!tmp0080.dontFree) h2_freeReg(tmp0079.regNro); + tmp0081 = power_genR_3(tmp0081, tmp0080, immValueZero); + tmp0082 = power_genMUL_3(tmp0082, tmp0081, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][3]))}); + if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); + tmp0083 = power_genADD_3(tmp0083, tmp0078, tmp0082); + if (!tmp0083.dontFree) h2_freeReg(tmp0078.regNro); + if (!tmp0083.dontFree) h2_freeReg(tmp0082.regNro); + power_genW_3(tmp0064, tmp0083, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +d_t VectorMatrixProductUnrolled (vector_t o, vector_t i, matrix_t m) +{ + o[0] = i[0]*m[0][0] + i[1]*m[1][0] + i[2]*m[2][0] + i[3]*m[3][0]; + o[1] = i[0]*m[0][1] + i[1]*m[1][1] + i[2]*m[2][1] + i[3]*m[3][1]; + o[2] = i[0]*m[0][2] + i[1]*m[1][2] + i[2]*m[2][2] + i[3]*m[3][2]; + o[3] = i[0]*m[0][3] + i[1]*m[1][3] + i[2]*m[2][3] + i[3]*m[3][3]; + return o[3]; +} + +#if 0 // What the binary code should be with a translation matrix +d_t VectorMatrixProductUnrolledSR(vector_t o, vector_t i, matrix_t m) +{ + + o[0] = m[0][0] * i[0] + + m[3][0] * i[3]; + o[1] = m[1][1] * i[1] + + m[3][1] * i[3]; + o[2] = m[2][2] * i[2] + m[3][2] * i[3]; + o[3] = + i[3]; + return o[3]; +} +#endif +d_t VectorMatrixProduct (vector_t o, vector_t i, matrix_t m) +{ + for (int column = 0; column < T; column++) + { + o[column] = 0; + for (int line = 0; line < T; line++) + { + o[column] += i[line] * m[line][column]; + + } + } + return o[3]; +} + + +int VectorMatrixProductCount(matrix_t mat) +{ + int op = 0; + for (int column = 0; column < T; column++) + { + for (int line = 0; line < T; line++) + { + switch (mat[line][column]) + { + case 0 : op += 0; break; + case 1 : op += 1; break; + default: op += 2; break; + } + } + } + return op; +} + + +void printMatrix (matrix_t m, char msg[]) +{ + printf ("%s:\n", msg); + for (int column = 0; column < T; column++) + { + for (int line = 0; line < T; line++) + { + printf ("%4d ", m[line][column]); + } + printf ("\n"); + } + printf ("\n"); +} + +void printVector (vector_t v, char msg[]) +{ + for (int i = 0; i < T; i++) + printf ("%4d ", v[i]); + printf ("%s\n", msg); +} + +bool vectorCompare(vector_t ref[], vector_t other[], char * msg, int doPrint, int nVector) +{ + int has_differences = false; + for (int line = 0; line < nVector; line++) + for (int i = 0; i < T; i++) + { + if (ref[line][i] != other[line][i]) + has_differences = true; + if (doPrint) + printf("%4d ", other[line][i]); + } + /* printf("%s : ", msg); */ + /* printf(" %s\n", (has_differences)?"NOT OK":"OK"); */ + return has_differences; +} + +int main (int argc, char *argv[]) +{ + matrix_t m; + char *matrixName; + // vector_t in0 = {1, 2, 3, 4}, in1 = {5, 6, 7, 8}; + vector_t *out, *cout, *in; + uint64_t timeGeneral, timeCompilette; + pifvv vmProduct; + int tmp, doPrint, nXperiment; + unsigned long acc; + bool resultValid; + + if (argc != 19) + { + printf ("Not enough arguments %d\n", argc); + printf ("VectorMatrix ExperimentNumber MatrixName M11 M12 ... M44\n"); + exit (-1); + } + doPrint = 0; + acc = 0; + nXperiment = atoi (argv[1]); + matrixName = argv[2]; + for (int line = 0; line < 4; line++) + for (int column = 0; column < 4; column++) + { + m[line][column] = atoi (argv[3 + line*4+column]); + } +#ifdef VERBOSE + printMatrix(m, matrixName); +#endif + + in = calloc(nXperiment, sizeof (vector_t)); + out = calloc(nXperiment, sizeof (vector_t)); + cout = calloc(nXperiment, sizeof (vector_t)); + + for (int line = 0; line < nXperiment; line++) + for (int column = 0; column < 4; column++) + in[line][column] = random () % 1000; + + tmp = VectorMatrixProductCount (m); + printf("Operation count Matrix %s : %d theoretical speedup %.1f\n", matrixName, tmp, (0==tmp)?32:32.0/tmp); + +// Repeat one instruction and count ticks +#define DO(INSN, REPEAT, TIME) {uint64_t tickCount = h2_getticks();for (int i = 0; i < REPEAT; i++) INSN; TIME = h2_getticks() - tickCount;} + +#ifdef VERBOSE + printVector (in[0], "Input vector #0"); +#endif + + acc += VectorMatrixProduct (out[0], in[0], m); /* Cold start */ + DO(acc += VectorMatrixProduct (out[i], in[i], m), nXperiment, timeGeneral) + +#ifdef VERBOSE + printVector (out[0], "Output vector #0 (general)"); +#endif + +#if 0 // Possible test with a source level unrolled version + uint64_t timeUnrolled; + vector_t uout0, uout1; + acc += VectorMatrixProductUnrolled (uout0, in0, m); + DO(acc += VectorMatrixProductUnrolled (uout1, in1, m), nXperiment, timeUnrolled); + vectorCompare(out1, uout1, "Unrolled out0", doPrint); +#endif + + vmProduct = (pifvv) h2_malloc(1024); + vmProduct = genVectorMatrixProduct (vmProduct, m); + acc += vmProduct (cout[0], in[0]); + DO(acc += vmProduct (cout[i], in[i]), nXperiment, timeCompilette); + +#ifdef VERBOSE + printVector (cout[0], "Output vector #0 (compilette)"); +#endif + + resultValid = vectorCompare(out, cout, "Compilette", doPrint, nXperiment); + + printf ("%s;%d;%lu;%lu;%lld;%d;%s\n", + matrixName, nXperiment, + timeGeneral, timeCompilette, + h2_codeGenTime, h2_insnGenerated, + resultValid?"true":"false"); + return resultValid; +} diff --git a/Demos/VectorMatrix/VectorMatrix.riscv b/Demos/VectorMatrix/VectorMatrix.riscv new file mode 100755 index 0000000000000000000000000000000000000000..8eea702214e5f50c8ce2d86440163b9568f12d15 GIT binary patch literal 62544 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 v^J_wQ(MT@{7a+2q3lVv +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +void RV32I_RET__I_32_1(){ /* RET */ + riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_RET__I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SUB_RRR_I_32_1(int r3,int r1,int r2){ /* SUB */ + riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SUB_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_MV_RR_I_32_1(int r0,int r1){ /* MV */ + riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_MV_RR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_MV_RI_I_32_1(int r3,int i1){ /* MV */ + riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_MV_RI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SLLI_RRI_I_32_1(int r3,int r1,int i0){ /* SL */ + riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SLLI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SLL_RRR_I_32_1(int r3,int r1,int r2){ /* SL */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SLL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32M_MUL_RRR_I_32_1(int r3,int r1,int r2){ /* MUL */ + riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32M_MUL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_ADDI_RRI_I_32_1(int r1,int r0,int i0){ /* ADD */ + riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_ADDI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_ADD_RRR_I_32_1(int r3,int r1,int r2){ /* ADD */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_ADD_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_LB_RRI_I_8_1(int r3,int r1,int i1){ /* R */ + riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_LB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void RV32I_LH_RRI_I_16_1(int r3,int r1,int i1){ /* R */ + riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_LH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void RV32I_LW_RRI_I_32_1(int r3,int r1,int i1){ /* R */ + riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_LW_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SRLI_RRI_I_32_1(int r3,int r1,int i0){ /* SR */ + riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SRLI_RRI_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SRL_RRR_I_32_1(int r3,int r1,int r2){ /* SR */ + riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SRL_RRR_I_32_1\n", h2_asm_pc); +#endif +} +void RV32I_SB_RRI_I_8_1(int r1,int r2,int i1){ /* W */ + riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SB_RRI_I_8_1\n", h2_asm_pc); +#endif +} +void RV32I_SH_RRI_I_16_1(int r1,int r2,int i1){ /* W */ + riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SH_RRI_I_16_1\n", h2_asm_pc); +#endif +} +void RV32I_SW_RRI_I_32_1(int r1,int r2,int i1){ /* W */ + riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); +#ifdef H2_DEBUG_INSN +printf("%p : RV32I_SW_RRI_I_32_1\n", h2_asm_pc); +#endif +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +/* -*- c -*- */ +// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/mesa/math/m_matrix.c +#include +#include +#include +#include +#define T 4 +typedef int d_t; +typedef d_t matrix_t [T][T]; +typedef d_t vector_t [T]; +typedef d_t (*pifvv)(vector_t, vector_t); + +pifvv genVectorMatrixProduct(pifvv ptr, matrix_t m) +{ + /* Code Generation of 5 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t o = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xF1F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp0000 = riscv_genMUL_4(tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0001 = riscv_genADD_3(tmp0001, o, tmp0000); + if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); + tmp0002 = riscv_genMUL_4(tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0003 = riscv_genADD_3(tmp0003, i, tmp0002); + if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); + tmp0004 = riscv_genR_3(tmp0004, tmp0003, immValueZero); + tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][0]))}, immValueZero); + if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); + tmp0006 = riscv_genMUL_4(tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0007 = riscv_genADD_3(tmp0007, i, tmp0006); + if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); + tmp0008 = riscv_genR_3(tmp0008, tmp0007, immValueZero); + tmp0009 = riscv_genMUL_4(tmp0009, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][0]))}, immValueZero); + if (!tmp0009.dontFree) h2_freeReg(tmp0008.regNro); + tmp0010 = riscv_genADD_3(tmp0010, tmp0005, tmp0009); + if (!tmp0010.dontFree) h2_freeReg(tmp0005.regNro); + if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); + tmp0011 = riscv_genMUL_4(tmp0011, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0012 = riscv_genADD_3(tmp0012, i, tmp0011); + if (!tmp0012.dontFree) h2_freeReg(tmp0011.regNro); + tmp0013 = riscv_genR_3(tmp0013, tmp0012, immValueZero); + tmp0014 = riscv_genMUL_4(tmp0014, tmp0013, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][0]))}, immValueZero); + if (!tmp0014.dontFree) h2_freeReg(tmp0013.regNro); + tmp0015 = riscv_genADD_3(tmp0015, tmp0010, tmp0014); + if (!tmp0015.dontFree) h2_freeReg(tmp0010.regNro); + if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); + tmp0016 = riscv_genMUL_4(tmp0016, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0017 = riscv_genADD_3(tmp0017, i, tmp0016); + if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); + tmp0018 = riscv_genR_3(tmp0018, tmp0017, immValueZero); + tmp0019 = riscv_genMUL_4(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][0]))}, immValueZero); + if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); + tmp0020 = riscv_genADD_3(tmp0020, tmp0015, tmp0019); + if (!tmp0020.dontFree) h2_freeReg(tmp0015.regNro); + if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); + riscv_genW_3(tmp0001, tmp0020, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0021 = riscv_genMUL_4(tmp0021, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0022 = riscv_genADD_3(tmp0022, o, tmp0021); + if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); + tmp0023 = riscv_genMUL_4(tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0024 = riscv_genADD_3(tmp0024, i, tmp0023); + if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); + tmp0025 = riscv_genR_3(tmp0025, tmp0024, immValueZero); + tmp0026 = riscv_genMUL_4(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][1]))}, immValueZero); + if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); + tmp0027 = riscv_genMUL_4(tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0028 = riscv_genADD_3(tmp0028, i, tmp0027); + if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); + tmp0029 = riscv_genR_3(tmp0029, tmp0028, immValueZero); + tmp0030 = riscv_genMUL_4(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][1]))}, immValueZero); + if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); + tmp0031 = riscv_genADD_3(tmp0031, tmp0026, tmp0030); + if (!tmp0031.dontFree) h2_freeReg(tmp0026.regNro); + if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); + tmp0032 = riscv_genMUL_4(tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0033 = riscv_genADD_3(tmp0033, i, tmp0032); + if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); + tmp0034 = riscv_genR_3(tmp0034, tmp0033, immValueZero); + tmp0035 = riscv_genMUL_4(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][1]))}, immValueZero); + if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); + tmp0036 = riscv_genADD_3(tmp0036, tmp0031, tmp0035); + if (!tmp0036.dontFree) h2_freeReg(tmp0031.regNro); + if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); + tmp0037 = riscv_genMUL_4(tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0038 = riscv_genADD_3(tmp0038, i, tmp0037); + if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); + tmp0039 = riscv_genR_3(tmp0039, tmp0038, immValueZero); + tmp0040 = riscv_genMUL_4(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][1]))}, immValueZero); + if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); + tmp0041 = riscv_genADD_3(tmp0041, tmp0036, tmp0040); + if (!tmp0041.dontFree) h2_freeReg(tmp0036.regNro); + if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); + riscv_genW_3(tmp0022, tmp0041, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0042 = riscv_genMUL_4(tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0043 = riscv_genADD_3(tmp0043, o, tmp0042); + if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); + tmp0044 = riscv_genMUL_4(tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0045 = riscv_genADD_3(tmp0045, i, tmp0044); + if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); + tmp0046 = riscv_genR_3(tmp0046, tmp0045, immValueZero); + tmp0047 = riscv_genMUL_4(tmp0047, tmp0046, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][2]))}, immValueZero); + if (!tmp0047.dontFree) h2_freeReg(tmp0046.regNro); + tmp0048 = riscv_genMUL_4(tmp0048, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0049 = riscv_genADD_3(tmp0049, i, tmp0048); + if (!tmp0049.dontFree) h2_freeReg(tmp0048.regNro); + tmp0050 = riscv_genR_3(tmp0050, tmp0049, immValueZero); + tmp0051 = riscv_genMUL_4(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][2]))}, immValueZero); + if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); + tmp0052 = riscv_genADD_3(tmp0052, tmp0047, tmp0051); + if (!tmp0052.dontFree) h2_freeReg(tmp0047.regNro); + if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); + tmp0053 = riscv_genMUL_4(tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0054 = riscv_genADD_3(tmp0054, i, tmp0053); + if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); + tmp0055 = riscv_genR_3(tmp0055, tmp0054, immValueZero); + tmp0056 = riscv_genMUL_4(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][2]))}, immValueZero); + if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); + tmp0057 = riscv_genADD_3(tmp0057, tmp0052, tmp0056); + if (!tmp0057.dontFree) h2_freeReg(tmp0052.regNro); + if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); + tmp0058 = riscv_genMUL_4(tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0059 = riscv_genADD_3(tmp0059, i, tmp0058); + if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); + tmp0060 = riscv_genR_3(tmp0060, tmp0059, immValueZero); + tmp0061 = riscv_genMUL_4(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][2]))}, immValueZero); + if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); + tmp0062 = riscv_genADD_3(tmp0062, tmp0057, tmp0061); + if (!tmp0062.dontFree) h2_freeReg(tmp0057.regNro); + if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); + riscv_genW_3(tmp0043, tmp0062, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp0063 = riscv_genMUL_4(tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0064 = riscv_genADD_3(tmp0064, o, tmp0063); + if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); + tmp0065 = riscv_genMUL_4(tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0066 = riscv_genADD_3(tmp0066, i, tmp0065); + if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); + tmp0067 = riscv_genR_3(tmp0067, tmp0066, immValueZero); + tmp0068 = riscv_genMUL_4(tmp0068, tmp0067, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][3]))}, immValueZero); + if (!tmp0068.dontFree) h2_freeReg(tmp0067.regNro); + tmp0069 = riscv_genMUL_4(tmp0069, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0070 = riscv_genADD_3(tmp0070, i, tmp0069); + if (!tmp0070.dontFree) h2_freeReg(tmp0069.regNro); + tmp0071 = riscv_genR_3(tmp0071, tmp0070, immValueZero); + tmp0072 = riscv_genMUL_4(tmp0072, tmp0071, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][3]))}, immValueZero); + if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); + tmp0073 = riscv_genADD_3(tmp0073, tmp0068, tmp0072); + if (!tmp0073.dontFree) h2_freeReg(tmp0068.regNro); + if (!tmp0073.dontFree) h2_freeReg(tmp0072.regNro); + tmp0074 = riscv_genMUL_4(tmp0074, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0075 = riscv_genADD_3(tmp0075, i, tmp0074); + if (!tmp0075.dontFree) h2_freeReg(tmp0074.regNro); + tmp0076 = riscv_genR_3(tmp0076, tmp0075, immValueZero); + tmp0077 = riscv_genMUL_4(tmp0077, tmp0076, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][3]))}, immValueZero); + if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); + tmp0078 = riscv_genADD_3(tmp0078, tmp0073, tmp0077); + if (!tmp0078.dontFree) h2_freeReg(tmp0073.regNro); + if (!tmp0078.dontFree) h2_freeReg(tmp0077.regNro); + tmp0079 = riscv_genMUL_4(tmp0079, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); + tmp0080 = riscv_genADD_3(tmp0080, i, tmp0079); + if (!tmp0080.dontFree) h2_freeReg(tmp0079.regNro); + tmp0081 = riscv_genR_3(tmp0081, tmp0080, immValueZero); + tmp0082 = riscv_genMUL_4(tmp0082, tmp0081, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][3]))}, immValueZero); + if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); + tmp0083 = riscv_genADD_3(tmp0083, tmp0078, tmp0082); + if (!tmp0083.dontFree) h2_freeReg(tmp0078.regNro); + if (!tmp0083.dontFree) h2_freeReg(tmp0082.regNro); + riscv_genW_3(tmp0064, tmp0083, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return ptr; +} + +d_t VectorMatrixProductUnrolled (vector_t o, vector_t i, matrix_t m) +{ + o[0] = i[0]*m[0][0] + i[1]*m[1][0] + i[2]*m[2][0] + i[3]*m[3][0]; + o[1] = i[0]*m[0][1] + i[1]*m[1][1] + i[2]*m[2][1] + i[3]*m[3][1]; + o[2] = i[0]*m[0][2] + i[1]*m[1][2] + i[2]*m[2][2] + i[3]*m[3][2]; + o[3] = i[0]*m[0][3] + i[1]*m[1][3] + i[2]*m[2][3] + i[3]*m[3][3]; + return o[3]; +} + +#if 0 // What the binary code should be with a translation matrix +d_t VectorMatrixProductUnrolledSR(vector_t o, vector_t i, matrix_t m) +{ + + o[0] = m[0][0] * i[0] + + m[3][0] * i[3]; + o[1] = m[1][1] * i[1] + + m[3][1] * i[3]; + o[2] = m[2][2] * i[2] + m[3][2] * i[3]; + o[3] = + i[3]; + return o[3]; +} +#endif +d_t VectorMatrixProduct (vector_t o, vector_t i, matrix_t m) +{ + for (int column = 0; column < T; column++) + { + o[column] = 0; + for (int line = 0; line < T; line++) + { + o[column] += i[line] * m[line][column]; + + } + } + return o[3]; +} + + +int VectorMatrixProductCount(matrix_t mat) +{ + int op = 0; + for (int column = 0; column < T; column++) + { + for (int line = 0; line < T; line++) + { + switch (mat[line][column]) + { + case 0 : op += 0; break; + case 1 : op += 1; break; + default: op += 2; break; + } + } + } + return op; +} + + +void printMatrix (matrix_t m, char msg[]) +{ + printf ("%s:\n", msg); + for (int column = 0; column < T; column++) + { + for (int line = 0; line < T; line++) + { + printf ("%4d ", m[line][column]); + } + printf ("\n"); + } + printf ("\n"); +} + +void printVector (vector_t v, char msg[]) +{ + for (int i = 0; i < T; i++) + printf ("%4d ", v[i]); + printf ("%s\n", msg); +} + +bool vectorCompare(vector_t ref[], vector_t other[], char * msg, int doPrint, int nVector) +{ + int has_differences = false; + for (int line = 0; line < nVector; line++) + for (int i = 0; i < T; i++) + { + if (ref[line][i] != other[line][i]) + has_differences = true; + if (doPrint) + printf("%4d ", other[line][i]); + } + /* printf("%s : ", msg); */ + /* printf(" %s\n", (has_differences)?"NOT OK":"OK"); */ + return has_differences; +} + +int main (int argc, char *argv[]) +{ + matrix_t m; + char *matrixName; + // vector_t in0 = {1, 2, 3, 4}, in1 = {5, 6, 7, 8}; + vector_t *out, *cout, *in; + uint64_t timeGeneral, timeCompilette; + pifvv vmProduct; + int tmp, doPrint, nXperiment; + unsigned long acc; + bool resultValid; + + if (argc != 19) + { + printf ("Not enough arguments %d\n", argc); + printf ("VectorMatrix ExperimentNumber MatrixName M11 M12 ... M44\n"); + exit (-1); + } + doPrint = 0; + acc = 0; + nXperiment = atoi (argv[1]); + matrixName = argv[2]; + for (int line = 0; line < 4; line++) + for (int column = 0; column < 4; column++) + { + m[line][column] = atoi (argv[3 + line*4+column]); + } +#ifdef VERBOSE + printMatrix(m, matrixName); +#endif + + in = calloc(nXperiment, sizeof (vector_t)); + out = calloc(nXperiment, sizeof (vector_t)); + cout = calloc(nXperiment, sizeof (vector_t)); + + for (int line = 0; line < nXperiment; line++) + for (int column = 0; column < 4; column++) + in[line][column] = random () % 1000; + + tmp = VectorMatrixProductCount (m); + printf("Operation count Matrix %s : %d theoretical speedup %.1f\n", matrixName, tmp, (0==tmp)?32:32.0/tmp); + +// Repeat one instruction and count ticks +#define DO(INSN, REPEAT, TIME) {uint64_t tickCount = h2_getticks();for (int i = 0; i < REPEAT; i++) INSN; TIME = h2_getticks() - tickCount;} + +#ifdef VERBOSE + printVector (in[0], "Input vector #0"); +#endif + + acc += VectorMatrixProduct (out[0], in[0], m); /* Cold start */ + DO(acc += VectorMatrixProduct (out[i], in[i], m), nXperiment, timeGeneral) + +#ifdef VERBOSE + printVector (out[0], "Output vector #0 (general)"); +#endif + +#if 0 // Possible test with a source level unrolled version + uint64_t timeUnrolled; + vector_t uout0, uout1; + acc += VectorMatrixProductUnrolled (uout0, in0, m); + DO(acc += VectorMatrixProductUnrolled (uout1, in1, m), nXperiment, timeUnrolled); + vectorCompare(out1, uout1, "Unrolled out0", doPrint); +#endif + + vmProduct = (pifvv) h2_malloc(1024); + vmProduct = genVectorMatrixProduct (vmProduct, m); + acc += vmProduct (cout[0], in[0]); + DO(acc += vmProduct (cout[i], in[i]), nXperiment, timeCompilette); + +#ifdef VERBOSE + printVector (cout[0], "Output vector #0 (compilette)"); +#endif + + resultValid = vectorCompare(out, cout, "Compilette", doPrint, nXperiment); + + printf ("%s;%d;%lu;%lu;%lld;%d;%s\n", + matrixName, nXperiment, + timeGeneral, timeCompilette, + h2_codeGenTime, h2_insnGenerated, + resultValid?"true":"false"); + return resultValid; +} diff --git a/HybroGen/IsaDescription.interp b/HybroGen/IsaDescription.interp new file mode 100644 index 0000000..c1157f7 --- /dev/null +++ b/HybroGen/IsaDescription.interp @@ -0,0 +1,58 @@ +token literal names: +null +'ARCH' +'|' +'[' +']' +'i' +'u' +'f' +null +null +null +null +null +':' +null + +token symbolic names: +null +null +null +null +null +null +null +null +WS +COMMENT +INT +NAME +NEWLINE +SEMICOL +CINLINE + +rule names: +isadescription +headerlines +archline +isalines +commentline +isaline +emptyline +bindescr +binelem +binvalue +regbin +expbin +asmdescr +extname +arith +opname +regName +semname +reglist + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 16, 133, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 6, 3, 47, 10, 3, 13, 3, 14, 3, 48, 3, 4, 3, 4, 3, 4, 6, 4, 54, 10, 4, 13, 4, 14, 4, 55, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 7, 5, 63, 10, 5, 12, 5, 14, 5, 66, 11, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 6, 9, 78, 10, 9, 13, 9, 14, 9, 79, 3, 10, 3, 10, 3, 10, 5, 10, 85, 10, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 94, 10, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 103, 10, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 5, 14, 114, 10, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 7, 20, 128, 10, 20, 12, 20, 14, 20, 131, 11, 20, 3, 20, 2, 2, 21, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 2, 3, 3, 2, 7, 9, 2, 127, 2, 40, 3, 2, 2, 2, 4, 46, 3, 2, 2, 2, 6, 50, 3, 2, 2, 2, 8, 64, 3, 2, 2, 2, 10, 67, 3, 2, 2, 2, 12, 69, 3, 2, 2, 2, 14, 74, 3, 2, 2, 2, 16, 77, 3, 2, 2, 2, 18, 84, 3, 2, 2, 2, 20, 86, 3, 2, 2, 2, 22, 88, 3, 2, 2, 2, 24, 97, 3, 2, 2, 2, 26, 106, 3, 2, 2, 2, 28, 115, 3, 2, 2, 2, 30, 117, 3, 2, 2, 2, 32, 119, 3, 2, 2, 2, 34, 121, 3, 2, 2, 2, 36, 123, 3, 2, 2, 2, 38, 125, 3, 2, 2, 2, 40, 41, 5, 4, 3, 2, 41, 42, 5, 8, 5, 2, 42, 3, 3, 2, 2, 2, 43, 47, 5, 10, 6, 2, 44, 47, 5, 6, 4, 2, 45, 47, 5, 14, 8, 2, 46, 43, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 46, 45, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 48, 49, 3, 2, 2, 2, 49, 5, 3, 2, 2, 2, 50, 51, 7, 3, 2, 2, 51, 53, 7, 13, 2, 2, 52, 54, 7, 12, 2, 2, 53, 52, 3, 2, 2, 2, 54, 55, 3, 2, 2, 2, 55, 53, 3, 2, 2, 2, 55, 56, 3, 2, 2, 2, 56, 57, 3, 2, 2, 2, 57, 58, 7, 14, 2, 2, 58, 7, 3, 2, 2, 2, 59, 63, 5, 10, 6, 2, 60, 63, 5, 14, 8, 2, 61, 63, 5, 12, 7, 2, 62, 59, 3, 2, 2, 2, 62, 60, 3, 2, 2, 2, 62, 61, 3, 2, 2, 2, 63, 66, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 9, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 67, 68, 7, 11, 2, 2, 68, 11, 3, 2, 2, 2, 69, 70, 5, 16, 9, 2, 70, 71, 7, 4, 2, 2, 71, 72, 5, 26, 14, 2, 72, 73, 7, 14, 2, 2, 73, 13, 3, 2, 2, 2, 74, 75, 7, 14, 2, 2, 75, 15, 3, 2, 2, 2, 76, 78, 5, 18, 10, 2, 77, 76, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 77, 3, 2, 2, 2, 79, 80, 3, 2, 2, 2, 80, 17, 3, 2, 2, 2, 81, 85, 5, 20, 11, 2, 82, 85, 5, 22, 12, 2, 83, 85, 5, 24, 13, 2, 84, 81, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 83, 3, 2, 2, 2, 85, 19, 3, 2, 2, 2, 86, 87, 7, 12, 2, 2, 87, 21, 3, 2, 2, 2, 88, 89, 7, 13, 2, 2, 89, 90, 7, 5, 2, 2, 90, 93, 7, 12, 2, 2, 91, 92, 7, 15, 2, 2, 92, 94, 7, 12, 2, 2, 93, 91, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 96, 7, 6, 2, 2, 96, 23, 3, 2, 2, 2, 97, 98, 7, 16, 2, 2, 98, 99, 7, 5, 2, 2, 99, 102, 7, 12, 2, 2, 100, 101, 7, 15, 2, 2, 101, 103, 7, 12, 2, 2, 102, 100, 3, 2, 2, 2, 102, 103, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 105, 7, 6, 2, 2, 105, 25, 3, 2, 2, 2, 106, 107, 5, 28, 15, 2, 107, 108, 5, 30, 16, 2, 108, 109, 7, 12, 2, 2, 109, 110, 7, 12, 2, 2, 110, 111, 5, 36, 19, 2, 111, 113, 5, 32, 17, 2, 112, 114, 5, 38, 20, 2, 113, 112, 3, 2, 2, 2, 113, 114, 3, 2, 2, 2, 114, 27, 3, 2, 2, 2, 115, 116, 7, 13, 2, 2, 116, 29, 3, 2, 2, 2, 117, 118, 9, 2, 2, 2, 118, 31, 3, 2, 2, 2, 119, 120, 7, 13, 2, 2, 120, 33, 3, 2, 2, 2, 121, 122, 7, 13, 2, 2, 122, 35, 3, 2, 2, 2, 123, 124, 7, 13, 2, 2, 124, 37, 3, 2, 2, 2, 125, 129, 5, 34, 18, 2, 126, 128, 5, 34, 18, 2, 127, 126, 3, 2, 2, 2, 128, 131, 3, 2, 2, 2, 129, 127, 3, 2, 2, 2, 129, 130, 3, 2, 2, 2, 130, 39, 3, 2, 2, 2, 131, 129, 3, 2, 2, 2, 13, 46, 48, 55, 62, 64, 79, 84, 93, 102, 113, 129] \ No newline at end of file diff --git a/HybroGen/IsaDescription.tokens b/HybroGen/IsaDescription.tokens new file mode 100644 index 0000000..2dcd920 --- /dev/null +++ b/HybroGen/IsaDescription.tokens @@ -0,0 +1,22 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +WS=8 +COMMENT=9 +INT=10 +NAME=11 +NEWLINE=12 +SEMICOL=13 +CINLINE=14 +'ARCH'=1 +'|'=2 +'['=3 +']'=4 +'i'=5 +'u'=6 +'f'=7 +':'=13 diff --git a/HybroGen/IsaDescriptionLexer.interp b/HybroGen/IsaDescriptionLexer.interp new file mode 100644 index 0000000..23a6756 --- /dev/null +++ b/HybroGen/IsaDescriptionLexer.interp @@ -0,0 +1,59 @@ +token literal names: +null +'ARCH' +'|' +'[' +']' +'i' +'u' +'f' +null +null +null +null +null +':' +null + +token symbolic names: +null +null +null +null +null +null +null +null +WS +COMMENT +INT +NAME +NEWLINE +SEMICOL +CINLINE + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +WS +COMMENT +INT +NAME +NEWLINE +SEMICOL +CINLINE + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 16, 91, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 6, 9, 50, 10, 9, 13, 9, 14, 9, 51, 3, 9, 3, 9, 3, 10, 3, 10, 7, 10, 58, 10, 10, 12, 10, 14, 10, 61, 11, 10, 3, 10, 3, 10, 3, 11, 6, 11, 66, 10, 11, 13, 11, 14, 11, 67, 3, 12, 3, 12, 7, 12, 72, 10, 12, 12, 12, 14, 12, 75, 11, 12, 3, 13, 5, 13, 78, 10, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 6, 15, 86, 10, 15, 13, 15, 14, 15, 87, 3, 15, 3, 15, 3, 59, 2, 16, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 3, 2, 7, 4, 2, 11, 11, 34, 34, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 7, 2, 48, 48, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 127, 127, 2, 96, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 3, 31, 3, 2, 2, 2, 5, 36, 3, 2, 2, 2, 7, 38, 3, 2, 2, 2, 9, 40, 3, 2, 2, 2, 11, 42, 3, 2, 2, 2, 13, 44, 3, 2, 2, 2, 15, 46, 3, 2, 2, 2, 17, 49, 3, 2, 2, 2, 19, 55, 3, 2, 2, 2, 21, 65, 3, 2, 2, 2, 23, 69, 3, 2, 2, 2, 25, 77, 3, 2, 2, 2, 27, 81, 3, 2, 2, 2, 29, 83, 3, 2, 2, 2, 31, 32, 7, 67, 2, 2, 32, 33, 7, 84, 2, 2, 33, 34, 7, 69, 2, 2, 34, 35, 7, 74, 2, 2, 35, 4, 3, 2, 2, 2, 36, 37, 7, 126, 2, 2, 37, 6, 3, 2, 2, 2, 38, 39, 7, 93, 2, 2, 39, 8, 3, 2, 2, 2, 40, 41, 7, 95, 2, 2, 41, 10, 3, 2, 2, 2, 42, 43, 7, 107, 2, 2, 43, 12, 3, 2, 2, 2, 44, 45, 7, 119, 2, 2, 45, 14, 3, 2, 2, 2, 46, 47, 7, 104, 2, 2, 47, 16, 3, 2, 2, 2, 48, 50, 9, 2, 2, 2, 49, 48, 3, 2, 2, 2, 50, 51, 3, 2, 2, 2, 51, 49, 3, 2, 2, 2, 51, 52, 3, 2, 2, 2, 52, 53, 3, 2, 2, 2, 53, 54, 8, 9, 2, 2, 54, 18, 3, 2, 2, 2, 55, 59, 7, 37, 2, 2, 56, 58, 11, 2, 2, 2, 57, 56, 3, 2, 2, 2, 58, 61, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 59, 57, 3, 2, 2, 2, 60, 62, 3, 2, 2, 2, 61, 59, 3, 2, 2, 2, 62, 63, 5, 25, 13, 2, 63, 20, 3, 2, 2, 2, 64, 66, 9, 3, 2, 2, 65, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 65, 3, 2, 2, 2, 67, 68, 3, 2, 2, 2, 68, 22, 3, 2, 2, 2, 69, 73, 9, 4, 2, 2, 70, 72, 9, 5, 2, 2, 71, 70, 3, 2, 2, 2, 72, 75, 3, 2, 2, 2, 73, 71, 3, 2, 2, 2, 73, 74, 3, 2, 2, 2, 74, 24, 3, 2, 2, 2, 75, 73, 3, 2, 2, 2, 76, 78, 7, 15, 2, 2, 77, 76, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 80, 7, 12, 2, 2, 80, 26, 3, 2, 2, 2, 81, 82, 7, 60, 2, 2, 82, 28, 3, 2, 2, 2, 83, 85, 7, 125, 2, 2, 84, 86, 10, 6, 2, 2, 85, 84, 3, 2, 2, 2, 86, 87, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 89, 3, 2, 2, 2, 89, 90, 7, 127, 2, 2, 90, 30, 3, 2, 2, 2, 9, 2, 51, 59, 67, 73, 77, 87, 3, 8, 2, 2] \ No newline at end of file diff --git a/HybroGen/IsaDescriptionLexer.py b/HybroGen/IsaDescriptionLexer.py new file mode 100644 index 0000000..1ace933 --- /dev/null +++ b/HybroGen/IsaDescriptionLexer.py @@ -0,0 +1,92 @@ +# Generated from IsaDescription.g4 by ANTLR 4.9.2 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + + +def serializedATN(): + with StringIO() as buf: + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\20") + buf.write("[\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") + buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") + buf.write("\t\16\4\17\t\17\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3") + buf.write("\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\6\t\62\n\t\r\t\16\t") + buf.write("\63\3\t\3\t\3\n\3\n\7\n:\n\n\f\n\16\n=\13\n\3\n\3\n\3") + buf.write("\13\6\13B\n\13\r\13\16\13C\3\f\3\f\7\fH\n\f\f\f\16\fK") + buf.write("\13\f\3\r\5\rN\n\r\3\r\3\r\3\16\3\16\3\17\3\17\6\17V\n") + buf.write("\17\r\17\16\17W\3\17\3\17\3;\2\20\3\3\5\4\7\5\t\6\13\7") + buf.write("\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\3\2\7") + buf.write("\4\2\13\13\"\"\3\2\62;\4\2C\\c|\7\2\60\60\62;C\\aac|\3") + buf.write("\2\177\177\2`\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t") + buf.write("\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3") + buf.write("\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2") + buf.write("\2\2\2\33\3\2\2\2\2\35\3\2\2\2\3\37\3\2\2\2\5$\3\2\2\2") + buf.write("\7&\3\2\2\2\t(\3\2\2\2\13*\3\2\2\2\r,\3\2\2\2\17.\3\2") + buf.write("\2\2\21\61\3\2\2\2\23\67\3\2\2\2\25A\3\2\2\2\27E\3\2\2") + buf.write("\2\31M\3\2\2\2\33Q\3\2\2\2\35S\3\2\2\2\37 \7C\2\2 !\7") + buf.write("T\2\2!\"\7E\2\2\"#\7J\2\2#\4\3\2\2\2$%\7~\2\2%\6\3\2\2") + buf.write("\2&\'\7]\2\2\'\b\3\2\2\2()\7_\2\2)\n\3\2\2\2*+\7k\2\2") + buf.write("+\f\3\2\2\2,-\7w\2\2-\16\3\2\2\2./\7h\2\2/\20\3\2\2\2") + buf.write("\60\62\t\2\2\2\61\60\3\2\2\2\62\63\3\2\2\2\63\61\3\2\2") + buf.write("\2\63\64\3\2\2\2\64\65\3\2\2\2\65\66\b\t\2\2\66\22\3\2") + buf.write("\2\2\67;\7%\2\28:\13\2\2\298\3\2\2\2:=\3\2\2\2;<\3\2\2") + buf.write("\2;9\3\2\2\2<>\3\2\2\2=;\3\2\2\2>?\5\31\r\2?\24\3\2\2") + buf.write("\2@B\t\3\2\2A@\3\2\2\2BC\3\2\2\2CA\3\2\2\2CD\3\2\2\2D") + buf.write("\26\3\2\2\2EI\t\4\2\2FH\t\5\2\2GF\3\2\2\2HK\3\2\2\2IG") + buf.write("\3\2\2\2IJ\3\2\2\2J\30\3\2\2\2KI\3\2\2\2LN\7\17\2\2ML") + buf.write("\3\2\2\2MN\3\2\2\2NO\3\2\2\2OP\7\f\2\2P\32\3\2\2\2QR\7") + buf.write("<\2\2R\34\3\2\2\2SU\7}\2\2TV\n\6\2\2UT\3\2\2\2VW\3\2\2") + buf.write("\2WU\3\2\2\2WX\3\2\2\2XY\3\2\2\2YZ\7\177\2\2Z\36\3\2\2") + buf.write("\2\t\2\63;CIMW\3\b\2\2") + return buf.getvalue() + + +class IsaDescriptionLexer(Lexer): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + T__0 = 1 + T__1 = 2 + T__2 = 3 + T__3 = 4 + T__4 = 5 + T__5 = 6 + T__6 = 7 + WS = 8 + COMMENT = 9 + INT = 10 + NAME = 11 + NEWLINE = 12 + SEMICOL = 13 + CINLINE = 14 + + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + + modeNames = [ "DEFAULT_MODE" ] + + literalNames = [ "", + "'ARCH'", "'|'", "'['", "']'", "'i'", "'u'", "'f'", "':'" ] + + symbolicNames = [ "", + "WS", "COMMENT", "INT", "NAME", "NEWLINE", "SEMICOL", "CINLINE" ] + + ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", + "WS", "COMMENT", "INT", "NAME", "NEWLINE", "SEMICOL", + "CINLINE" ] + + grammarFileName = "IsaDescription.g4" + + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.9.2") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + diff --git a/HybroGen/IsaDescriptionLexer.tokens b/HybroGen/IsaDescriptionLexer.tokens new file mode 100644 index 0000000..2dcd920 --- /dev/null +++ b/HybroGen/IsaDescriptionLexer.tokens @@ -0,0 +1,22 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +WS=8 +COMMENT=9 +INT=10 +NAME=11 +NEWLINE=12 +SEMICOL=13 +CINLINE=14 +'ARCH'=1 +'|'=2 +'['=3 +']'=4 +'i'=5 +'u'=6 +'f'=7 +':'=13 diff --git a/HybroGen/IsaDescriptionListener.py b/HybroGen/IsaDescriptionListener.py new file mode 100644 index 0000000..f1a6b6f --- /dev/null +++ b/HybroGen/IsaDescriptionListener.py @@ -0,0 +1,183 @@ +# Generated from IsaDescription.g4 by ANTLR 4.9.2 +from antlr4 import * +if __name__ is not None and "." in __name__: + from .IsaDescriptionParser import IsaDescriptionParser +else: + from IsaDescriptionParser import IsaDescriptionParser + +# This class defines a complete listener for a parse tree produced by IsaDescriptionParser. +class IsaDescriptionListener(ParseTreeListener): + + # Enter a parse tree produced by IsaDescriptionParser#isadescription. + def enterIsadescription(self, ctx:IsaDescriptionParser.IsadescriptionContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#isadescription. + def exitIsadescription(self, ctx:IsaDescriptionParser.IsadescriptionContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#headerlines. + def enterHeaderlines(self, ctx:IsaDescriptionParser.HeaderlinesContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#headerlines. + def exitHeaderlines(self, ctx:IsaDescriptionParser.HeaderlinesContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#archline. + def enterArchline(self, ctx:IsaDescriptionParser.ArchlineContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#archline. + def exitArchline(self, ctx:IsaDescriptionParser.ArchlineContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#isalines. + def enterIsalines(self, ctx:IsaDescriptionParser.IsalinesContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#isalines. + def exitIsalines(self, ctx:IsaDescriptionParser.IsalinesContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#commentline. + def enterCommentline(self, ctx:IsaDescriptionParser.CommentlineContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#commentline. + def exitCommentline(self, ctx:IsaDescriptionParser.CommentlineContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#isaline. + def enterIsaline(self, ctx:IsaDescriptionParser.IsalineContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#isaline. + def exitIsaline(self, ctx:IsaDescriptionParser.IsalineContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#emptyline. + def enterEmptyline(self, ctx:IsaDescriptionParser.EmptylineContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#emptyline. + def exitEmptyline(self, ctx:IsaDescriptionParser.EmptylineContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#bindescr. + def enterBindescr(self, ctx:IsaDescriptionParser.BindescrContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#bindescr. + def exitBindescr(self, ctx:IsaDescriptionParser.BindescrContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#binelem. + def enterBinelem(self, ctx:IsaDescriptionParser.BinelemContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#binelem. + def exitBinelem(self, ctx:IsaDescriptionParser.BinelemContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#binvalue. + def enterBinvalue(self, ctx:IsaDescriptionParser.BinvalueContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#binvalue. + def exitBinvalue(self, ctx:IsaDescriptionParser.BinvalueContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#regbin. + def enterRegbin(self, ctx:IsaDescriptionParser.RegbinContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#regbin. + def exitRegbin(self, ctx:IsaDescriptionParser.RegbinContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#expbin. + def enterExpbin(self, ctx:IsaDescriptionParser.ExpbinContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#expbin. + def exitExpbin(self, ctx:IsaDescriptionParser.ExpbinContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#asmdescr. + def enterAsmdescr(self, ctx:IsaDescriptionParser.AsmdescrContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#asmdescr. + def exitAsmdescr(self, ctx:IsaDescriptionParser.AsmdescrContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#extname. + def enterExtname(self, ctx:IsaDescriptionParser.ExtnameContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#extname. + def exitExtname(self, ctx:IsaDescriptionParser.ExtnameContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#arith. + def enterArith(self, ctx:IsaDescriptionParser.ArithContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#arith. + def exitArith(self, ctx:IsaDescriptionParser.ArithContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#opname. + def enterOpname(self, ctx:IsaDescriptionParser.OpnameContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#opname. + def exitOpname(self, ctx:IsaDescriptionParser.OpnameContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#regName. + def enterRegName(self, ctx:IsaDescriptionParser.RegNameContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#regName. + def exitRegName(self, ctx:IsaDescriptionParser.RegNameContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#semname. + def enterSemname(self, ctx:IsaDescriptionParser.SemnameContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#semname. + def exitSemname(self, ctx:IsaDescriptionParser.SemnameContext): + pass + + + # Enter a parse tree produced by IsaDescriptionParser#reglist. + def enterReglist(self, ctx:IsaDescriptionParser.ReglistContext): + pass + + # Exit a parse tree produced by IsaDescriptionParser#reglist. + def exitReglist(self, ctx:IsaDescriptionParser.ReglistContext): + pass + + + +del IsaDescriptionParser \ No newline at end of file diff --git a/HybroGen/IsaDescriptionParser.py b/HybroGen/IsaDescriptionParser.py new file mode 100644 index 0000000..cd79c81 --- /dev/null +++ b/HybroGen/IsaDescriptionParser.py @@ -0,0 +1,1179 @@ +# Generated from IsaDescription.g4 by ANTLR 4.9.2 +# encoding: utf-8 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + +def serializedATN(): + with StringIO() as buf: + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\20") + buf.write("\u0085\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") + buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") + buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") + buf.write("\4\24\t\24\3\2\3\2\3\2\3\3\3\3\3\3\6\3/\n\3\r\3\16\3\60") + buf.write("\3\4\3\4\3\4\6\4\66\n\4\r\4\16\4\67\3\4\3\4\3\5\3\5\3") + buf.write("\5\7\5?\n\5\f\5\16\5B\13\5\3\6\3\6\3\7\3\7\3\7\3\7\3\7") + buf.write("\3\b\3\b\3\t\6\tN\n\t\r\t\16\tO\3\n\3\n\3\n\5\nU\n\n\3") + buf.write("\13\3\13\3\f\3\f\3\f\3\f\3\f\5\f^\n\f\3\f\3\f\3\r\3\r") + buf.write("\3\r\3\r\3\r\5\rg\n\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16") + buf.write("\3\16\3\16\5\16r\n\16\3\17\3\17\3\20\3\20\3\21\3\21\3") + buf.write("\22\3\22\3\23\3\23\3\24\3\24\7\24\u0080\n\24\f\24\16\24") + buf.write("\u0083\13\24\3\24\2\2\25\2\4\6\b\n\f\16\20\22\24\26\30") + buf.write("\32\34\36 \"$&\2\3\3\2\7\t\2\177\2(\3\2\2\2\4.\3\2\2\2") + buf.write("\6\62\3\2\2\2\b@\3\2\2\2\nC\3\2\2\2\fE\3\2\2\2\16J\3\2") + buf.write("\2\2\20M\3\2\2\2\22T\3\2\2\2\24V\3\2\2\2\26X\3\2\2\2\30") + buf.write("a\3\2\2\2\32j\3\2\2\2\34s\3\2\2\2\36u\3\2\2\2 w\3\2\2") + buf.write("\2\"y\3\2\2\2${\3\2\2\2&}\3\2\2\2()\5\4\3\2)*\5\b\5\2") + buf.write("*\3\3\2\2\2+/\5\n\6\2,/\5\6\4\2-/\5\16\b\2.+\3\2\2\2.") + buf.write(",\3\2\2\2.-\3\2\2\2/\60\3\2\2\2\60.\3\2\2\2\60\61\3\2") + buf.write("\2\2\61\5\3\2\2\2\62\63\7\3\2\2\63\65\7\r\2\2\64\66\7") + buf.write("\f\2\2\65\64\3\2\2\2\66\67\3\2\2\2\67\65\3\2\2\2\678\3") + buf.write("\2\2\289\3\2\2\29:\7\16\2\2:\7\3\2\2\2;?\5\n\6\2;\3\2\2\2><\3\2\2\2>=\3\2\2\2?B\3\2\2\2") + buf.write("@>\3\2\2\2@A\3\2\2\2A\t\3\2\2\2B@\3\2\2\2CD\7\13\2\2D") + buf.write("\13\3\2\2\2EF\5\20\t\2FG\7\4\2\2GH\5\32\16\2HI\7\16\2") + buf.write("\2I\r\3\2\2\2JK\7\16\2\2K\17\3\2\2\2LN\5\22\n\2ML\3\2") + buf.write("\2\2NO\3\2\2\2OM\3\2\2\2OP\3\2\2\2P\21\3\2\2\2QU\5\24") + buf.write("\13\2RU\5\26\f\2SU\5\30\r\2TQ\3\2\2\2TR\3\2\2\2TS\3\2") + buf.write("\2\2U\23\3\2\2\2VW\7\f\2\2W\25\3\2\2\2XY\7\r\2\2YZ\7\5") + buf.write("\2\2Z]\7\f\2\2[\\\7\17\2\2\\^\7\f\2\2][\3\2\2\2]^\3\2") + buf.write("\2\2^_\3\2\2\2_`\7\6\2\2`\27\3\2\2\2ab\7\20\2\2bc\7\5") + buf.write("\2\2cf\7\f\2\2de\7\17\2\2eg\7\f\2\2fd\3\2\2\2fg\3\2\2") + buf.write("\2gh\3\2\2\2hi\7\6\2\2i\31\3\2\2\2jk\5\34\17\2kl\5\36") + buf.write("\20\2lm\7\f\2\2mn\7\f\2\2no\5$\23\2oq\5 \21\2pr\5&\24") + buf.write("\2qp\3\2\2\2qr\3\2\2\2r\33\3\2\2\2st\7\r\2\2t\35\3\2\2") + buf.write("\2uv\t\2\2\2v\37\3\2\2\2wx\7\r\2\2x!\3\2\2\2yz\7\r\2\2") + buf.write("z#\3\2\2\2{|\7\r\2\2|%\3\2\2\2}\u0081\5\"\22\2~\u0080") + buf.write("\5\"\22\2\177~\3\2\2\2\u0080\u0083\3\2\2\2\u0081\177\3") + buf.write("\2\2\2\u0081\u0082\3\2\2\2\u0082\'\3\2\2\2\u0083\u0081") + buf.write("\3\2\2\2\r.\60\67>@OT]fq\u0081") + return buf.getvalue() + + +class IsaDescriptionParser ( Parser ): + + grammarFileName = "IsaDescription.g4" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ "", "'ARCH'", "'|'", "'['", "']'", "'i'", + "'u'", "'f'", "", "", "", + "", "", "':'" ] + + symbolicNames = [ "", "", "", "", + "", "", "", "", + "WS", "COMMENT", "INT", "NAME", "NEWLINE", "SEMICOL", + "CINLINE" ] + + RULE_isadescription = 0 + RULE_headerlines = 1 + RULE_archline = 2 + RULE_isalines = 3 + RULE_commentline = 4 + RULE_isaline = 5 + RULE_emptyline = 6 + RULE_bindescr = 7 + RULE_binelem = 8 + RULE_binvalue = 9 + RULE_regbin = 10 + RULE_expbin = 11 + RULE_asmdescr = 12 + RULE_extname = 13 + RULE_arith = 14 + RULE_opname = 15 + RULE_regName = 16 + RULE_semname = 17 + RULE_reglist = 18 + + ruleNames = [ "isadescription", "headerlines", "archline", "isalines", + "commentline", "isaline", "emptyline", "bindescr", "binelem", + "binvalue", "regbin", "expbin", "asmdescr", "extname", + "arith", "opname", "regName", "semname", "reglist" ] + + EOF = Token.EOF + T__0=1 + T__1=2 + T__2=3 + T__3=4 + T__4=5 + T__5=6 + T__6=7 + WS=8 + COMMENT=9 + INT=10 + NAME=11 + NEWLINE=12 + SEMICOL=13 + CINLINE=14 + + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.9.2") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + + + + class IsadescriptionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def headerlines(self): + return self.getTypedRuleContext(IsaDescriptionParser.HeaderlinesContext,0) + + + def isalines(self): + return self.getTypedRuleContext(IsaDescriptionParser.IsalinesContext,0) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_isadescription + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterIsadescription" ): + listener.enterIsadescription(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitIsadescription" ): + listener.exitIsadescription(self) + + + + + def isadescription(self): + + localctx = IsaDescriptionParser.IsadescriptionContext(self, self._ctx, self.state) + self.enterRule(localctx, 0, self.RULE_isadescription) + try: + self.enterOuterAlt(localctx, 1) + self.state = 38 + self.headerlines() + self.state = 39 + self.isalines() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class HeaderlinesContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def commentline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.CommentlineContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.CommentlineContext,i) + + + def archline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.ArchlineContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.ArchlineContext,i) + + + def emptyline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.EmptylineContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.EmptylineContext,i) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_headerlines + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterHeaderlines" ): + listener.enterHeaderlines(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitHeaderlines" ): + listener.exitHeaderlines(self) + + + + + def headerlines(self): + + localctx = IsaDescriptionParser.HeaderlinesContext(self, self._ctx, self.state) + self.enterRule(localctx, 2, self.RULE_headerlines) + try: + self.enterOuterAlt(localctx, 1) + self.state = 44 + self._errHandler.sync(self) + _alt = 1 + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt == 1: + self.state = 44 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [IsaDescriptionParser.COMMENT]: + self.state = 41 + self.commentline() + pass + elif token in [IsaDescriptionParser.T__0]: + self.state = 42 + self.archline() + pass + elif token in [IsaDescriptionParser.NEWLINE]: + self.state = 43 + self.emptyline() + pass + else: + raise NoViableAltException(self) + + + else: + raise NoViableAltException(self) + self.state = 46 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,1,self._ctx) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ArchlineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(IsaDescriptionParser.NAME, 0) + + def NEWLINE(self): + return self.getToken(IsaDescriptionParser.NEWLINE, 0) + + def INT(self, i:int=None): + if i is None: + return self.getTokens(IsaDescriptionParser.INT) + else: + return self.getToken(IsaDescriptionParser.INT, i) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_archline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterArchline" ): + listener.enterArchline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitArchline" ): + listener.exitArchline(self) + + + + + def archline(self): + + localctx = IsaDescriptionParser.ArchlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 4, self.RULE_archline) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 48 + self.match(IsaDescriptionParser.T__0) + self.state = 49 + self.match(IsaDescriptionParser.NAME) + self.state = 51 + self._errHandler.sync(self) + _la = self._input.LA(1) + while True: + self.state = 50 + self.match(IsaDescriptionParser.INT) + self.state = 53 + self._errHandler.sync(self) + _la = self._input.LA(1) + if not (_la==IsaDescriptionParser.INT): + break + + self.state = 55 + self.match(IsaDescriptionParser.NEWLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class IsalinesContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def commentline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.CommentlineContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.CommentlineContext,i) + + + def emptyline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.EmptylineContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.EmptylineContext,i) + + + def isaline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.IsalineContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.IsalineContext,i) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_isalines + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterIsalines" ): + listener.enterIsalines(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitIsalines" ): + listener.exitIsalines(self) + + + + + def isalines(self): + + localctx = IsaDescriptionParser.IsalinesContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_isalines) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 62 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << IsaDescriptionParser.COMMENT) | (1 << IsaDescriptionParser.INT) | (1 << IsaDescriptionParser.NAME) | (1 << IsaDescriptionParser.NEWLINE) | (1 << IsaDescriptionParser.CINLINE))) != 0): + self.state = 60 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [IsaDescriptionParser.COMMENT]: + self.state = 57 + self.commentline() + pass + elif token in [IsaDescriptionParser.NEWLINE]: + self.state = 58 + self.emptyline() + pass + elif token in [IsaDescriptionParser.INT, IsaDescriptionParser.NAME, IsaDescriptionParser.CINLINE]: + self.state = 59 + self.isaline() + pass + else: + raise NoViableAltException(self) + + self.state = 64 + self._errHandler.sync(self) + _la = self._input.LA(1) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class CommentlineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def COMMENT(self): + return self.getToken(IsaDescriptionParser.COMMENT, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_commentline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterCommentline" ): + listener.enterCommentline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitCommentline" ): + listener.exitCommentline(self) + + + + + def commentline(self): + + localctx = IsaDescriptionParser.CommentlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_commentline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 65 + self.match(IsaDescriptionParser.COMMENT) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class IsalineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def bindescr(self): + return self.getTypedRuleContext(IsaDescriptionParser.BindescrContext,0) + + + def asmdescr(self): + return self.getTypedRuleContext(IsaDescriptionParser.AsmdescrContext,0) + + + def NEWLINE(self): + return self.getToken(IsaDescriptionParser.NEWLINE, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_isaline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterIsaline" ): + listener.enterIsaline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitIsaline" ): + listener.exitIsaline(self) + + + + + def isaline(self): + + localctx = IsaDescriptionParser.IsalineContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_isaline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 67 + self.bindescr() + self.state = 68 + self.match(IsaDescriptionParser.T__1) + self.state = 69 + self.asmdescr() + self.state = 70 + self.match(IsaDescriptionParser.NEWLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class EmptylineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NEWLINE(self): + return self.getToken(IsaDescriptionParser.NEWLINE, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_emptyline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterEmptyline" ): + listener.enterEmptyline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitEmptyline" ): + listener.exitEmptyline(self) + + + + + def emptyline(self): + + localctx = IsaDescriptionParser.EmptylineContext(self, self._ctx, self.state) + self.enterRule(localctx, 12, self.RULE_emptyline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 72 + self.match(IsaDescriptionParser.NEWLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class BindescrContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def binelem(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.BinelemContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.BinelemContext,i) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_bindescr + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterBindescr" ): + listener.enterBindescr(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitBindescr" ): + listener.exitBindescr(self) + + + + + def bindescr(self): + + localctx = IsaDescriptionParser.BindescrContext(self, self._ctx, self.state) + self.enterRule(localctx, 14, self.RULE_bindescr) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 75 + self._errHandler.sync(self) + _la = self._input.LA(1) + while True: + self.state = 74 + self.binelem() + self.state = 77 + self._errHandler.sync(self) + _la = self._input.LA(1) + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << IsaDescriptionParser.INT) | (1 << IsaDescriptionParser.NAME) | (1 << IsaDescriptionParser.CINLINE))) != 0)): + break + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class BinelemContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def binvalue(self): + return self.getTypedRuleContext(IsaDescriptionParser.BinvalueContext,0) + + + def regbin(self): + return self.getTypedRuleContext(IsaDescriptionParser.RegbinContext,0) + + + def expbin(self): + return self.getTypedRuleContext(IsaDescriptionParser.ExpbinContext,0) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_binelem + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterBinelem" ): + listener.enterBinelem(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitBinelem" ): + listener.exitBinelem(self) + + + + + def binelem(self): + + localctx = IsaDescriptionParser.BinelemContext(self, self._ctx, self.state) + self.enterRule(localctx, 16, self.RULE_binelem) + try: + self.state = 82 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [IsaDescriptionParser.INT]: + self.enterOuterAlt(localctx, 1) + self.state = 79 + self.binvalue() + pass + elif token in [IsaDescriptionParser.NAME]: + self.enterOuterAlt(localctx, 2) + self.state = 80 + self.regbin() + pass + elif token in [IsaDescriptionParser.CINLINE]: + self.enterOuterAlt(localctx, 3) + self.state = 81 + self.expbin() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class BinvalueContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def INT(self): + return self.getToken(IsaDescriptionParser.INT, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_binvalue + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterBinvalue" ): + listener.enterBinvalue(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitBinvalue" ): + listener.exitBinvalue(self) + + + + + def binvalue(self): + + localctx = IsaDescriptionParser.BinvalueContext(self, self._ctx, self.state) + self.enterRule(localctx, 18, self.RULE_binvalue) + try: + self.enterOuterAlt(localctx, 1) + self.state = 84 + self.match(IsaDescriptionParser.INT) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegbinContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(IsaDescriptionParser.NAME, 0) + + def INT(self, i:int=None): + if i is None: + return self.getTokens(IsaDescriptionParser.INT) + else: + return self.getToken(IsaDescriptionParser.INT, i) + + def SEMICOL(self): + return self.getToken(IsaDescriptionParser.SEMICOL, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_regbin + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegbin" ): + listener.enterRegbin(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegbin" ): + listener.exitRegbin(self) + + + + + def regbin(self): + + localctx = IsaDescriptionParser.RegbinContext(self, self._ctx, self.state) + self.enterRule(localctx, 20, self.RULE_regbin) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 86 + self.match(IsaDescriptionParser.NAME) + self.state = 87 + self.match(IsaDescriptionParser.T__2) + self.state = 88 + self.match(IsaDescriptionParser.INT) + self.state = 91 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==IsaDescriptionParser.SEMICOL: + self.state = 89 + self.match(IsaDescriptionParser.SEMICOL) + self.state = 90 + self.match(IsaDescriptionParser.INT) + + + self.state = 93 + self.match(IsaDescriptionParser.T__3) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ExpbinContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def CINLINE(self): + return self.getToken(IsaDescriptionParser.CINLINE, 0) + + def INT(self, i:int=None): + if i is None: + return self.getTokens(IsaDescriptionParser.INT) + else: + return self.getToken(IsaDescriptionParser.INT, i) + + def SEMICOL(self): + return self.getToken(IsaDescriptionParser.SEMICOL, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_expbin + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterExpbin" ): + listener.enterExpbin(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitExpbin" ): + listener.exitExpbin(self) + + + + + def expbin(self): + + localctx = IsaDescriptionParser.ExpbinContext(self, self._ctx, self.state) + self.enterRule(localctx, 22, self.RULE_expbin) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 95 + self.match(IsaDescriptionParser.CINLINE) + self.state = 96 + self.match(IsaDescriptionParser.T__2) + self.state = 97 + self.match(IsaDescriptionParser.INT) + self.state = 100 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==IsaDescriptionParser.SEMICOL: + self.state = 98 + self.match(IsaDescriptionParser.SEMICOL) + self.state = 99 + self.match(IsaDescriptionParser.INT) + + + self.state = 102 + self.match(IsaDescriptionParser.T__3) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class AsmdescrContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def extname(self): + return self.getTypedRuleContext(IsaDescriptionParser.ExtnameContext,0) + + + def arith(self): + return self.getTypedRuleContext(IsaDescriptionParser.ArithContext,0) + + + def INT(self, i:int=None): + if i is None: + return self.getTokens(IsaDescriptionParser.INT) + else: + return self.getToken(IsaDescriptionParser.INT, i) + + def semname(self): + return self.getTypedRuleContext(IsaDescriptionParser.SemnameContext,0) + + + def opname(self): + return self.getTypedRuleContext(IsaDescriptionParser.OpnameContext,0) + + + def reglist(self): + return self.getTypedRuleContext(IsaDescriptionParser.ReglistContext,0) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_asmdescr + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterAsmdescr" ): + listener.enterAsmdescr(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitAsmdescr" ): + listener.exitAsmdescr(self) + + + + + def asmdescr(self): + + localctx = IsaDescriptionParser.AsmdescrContext(self, self._ctx, self.state) + self.enterRule(localctx, 24, self.RULE_asmdescr) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 104 + self.extname() + self.state = 105 + self.arith() + self.state = 106 + self.match(IsaDescriptionParser.INT) + self.state = 107 + self.match(IsaDescriptionParser.INT) + self.state = 108 + self.semname() + self.state = 109 + self.opname() + self.state = 111 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==IsaDescriptionParser.NAME: + self.state = 110 + self.reglist() + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ExtnameContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(IsaDescriptionParser.NAME, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_extname + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterExtname" ): + listener.enterExtname(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitExtname" ): + listener.exitExtname(self) + + + + + def extname(self): + + localctx = IsaDescriptionParser.ExtnameContext(self, self._ctx, self.state) + self.enterRule(localctx, 26, self.RULE_extname) + try: + self.enterOuterAlt(localctx, 1) + self.state = 113 + self.match(IsaDescriptionParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ArithContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_arith + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterArith" ): + listener.enterArith(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitArith" ): + listener.exitArith(self) + + + + + def arith(self): + + localctx = IsaDescriptionParser.ArithContext(self, self._ctx, self.state) + self.enterRule(localctx, 28, self.RULE_arith) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 115 + _la = self._input.LA(1) + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << IsaDescriptionParser.T__4) | (1 << IsaDescriptionParser.T__5) | (1 << IsaDescriptionParser.T__6))) != 0)): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class OpnameContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(IsaDescriptionParser.NAME, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_opname + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterOpname" ): + listener.enterOpname(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitOpname" ): + listener.exitOpname(self) + + + + + def opname(self): + + localctx = IsaDescriptionParser.OpnameContext(self, self._ctx, self.state) + self.enterRule(localctx, 30, self.RULE_opname) + try: + self.enterOuterAlt(localctx, 1) + self.state = 117 + self.match(IsaDescriptionParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegNameContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(IsaDescriptionParser.NAME, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_regName + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegName" ): + listener.enterRegName(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegName" ): + listener.exitRegName(self) + + + + + def regName(self): + + localctx = IsaDescriptionParser.RegNameContext(self, self._ctx, self.state) + self.enterRule(localctx, 32, self.RULE_regName) + try: + self.enterOuterAlt(localctx, 1) + self.state = 119 + self.match(IsaDescriptionParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class SemnameContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(IsaDescriptionParser.NAME, 0) + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_semname + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterSemname" ): + listener.enterSemname(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitSemname" ): + listener.exitSemname(self) + + + + + def semname(self): + + localctx = IsaDescriptionParser.SemnameContext(self, self._ctx, self.state) + self.enterRule(localctx, 34, self.RULE_semname) + try: + self.enterOuterAlt(localctx, 1) + self.state = 121 + self.match(IsaDescriptionParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ReglistContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def regName(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(IsaDescriptionParser.RegNameContext) + else: + return self.getTypedRuleContext(IsaDescriptionParser.RegNameContext,i) + + + def getRuleIndex(self): + return IsaDescriptionParser.RULE_reglist + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterReglist" ): + listener.enterReglist(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitReglist" ): + listener.exitReglist(self) + + + + + def reglist(self): + + localctx = IsaDescriptionParser.ReglistContext(self, self._ctx, self.state) + self.enterRule(localctx, 36, self.RULE_reglist) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 123 + self.regName() + self.state = 127 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==IsaDescriptionParser.NAME: + self.state = 124 + self.regName() + self.state = 129 + self._errHandler.sync(self) + _la = self._input.LA(1) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + + + diff --git a/HybroGen/RegisterDescription.interp b/HybroGen/RegisterDescription.interp new file mode 100644 index 0000000..63bbb83 --- /dev/null +++ b/HybroGen/RegisterDescription.interp @@ -0,0 +1,50 @@ +token literal names: +null +'-' +'v' +'i' +'f' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +WS +COMMENT +INT +FUNCNAME +REGWN +NEWLINE +PREFIX +NAME + +rule names: +registerdescription +headerlines +commentline +emptyline +registerlines +registerline +registerlist +registerprefix +registerfunctionlist +registerfunction +registerfunctionwn +regbankvec +regbank +registerwidth +extension + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 14, 89, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 6, 3, 38, 10, 3, 13, 3, 14, 3, 39, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 6, 6, 49, 10, 6, 13, 6, 14, 6, 50, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 60, 10, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 5, 9, 67, 10, 9, 3, 10, 3, 10, 5, 10, 71, 10, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 5, 12, 78, 10, 12, 3, 13, 5, 13, 81, 10, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 2, 2, 17, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 2, 3, 3, 2, 5, 6, 2, 83, 2, 32, 3, 2, 2, 2, 4, 37, 3, 2, 2, 2, 6, 41, 3, 2, 2, 2, 8, 43, 3, 2, 2, 2, 10, 48, 3, 2, 2, 2, 12, 52, 3, 2, 2, 2, 14, 61, 3, 2, 2, 2, 16, 63, 3, 2, 2, 2, 18, 70, 3, 2, 2, 2, 20, 72, 3, 2, 2, 2, 22, 74, 3, 2, 2, 2, 24, 80, 3, 2, 2, 2, 26, 82, 3, 2, 2, 2, 28, 84, 3, 2, 2, 2, 30, 86, 3, 2, 2, 2, 32, 33, 5, 4, 3, 2, 33, 34, 5, 10, 6, 2, 34, 3, 3, 2, 2, 2, 35, 38, 5, 6, 4, 2, 36, 38, 5, 8, 5, 2, 37, 35, 3, 2, 2, 2, 37, 36, 3, 2, 2, 2, 38, 39, 3, 2, 2, 2, 39, 37, 3, 2, 2, 2, 39, 40, 3, 2, 2, 2, 40, 5, 3, 2, 2, 2, 41, 42, 7, 8, 2, 2, 42, 7, 3, 2, 2, 2, 43, 44, 7, 12, 2, 2, 44, 9, 3, 2, 2, 2, 45, 49, 5, 6, 4, 2, 46, 49, 5, 12, 7, 2, 47, 49, 5, 8, 5, 2, 48, 45, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 48, 47, 3, 2, 2, 2, 49, 50, 3, 2, 2, 2, 50, 48, 3, 2, 2, 2, 50, 51, 3, 2, 2, 2, 51, 11, 3, 2, 2, 2, 52, 53, 5, 30, 16, 2, 53, 54, 5, 24, 13, 2, 54, 55, 5, 26, 14, 2, 55, 56, 5, 14, 8, 2, 56, 57, 5, 28, 15, 2, 57, 59, 5, 18, 10, 2, 58, 60, 7, 12, 2, 2, 59, 58, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 60, 13, 3, 2, 2, 2, 61, 62, 5, 16, 9, 2, 62, 15, 3, 2, 2, 2, 63, 66, 7, 13, 2, 2, 64, 65, 7, 3, 2, 2, 65, 67, 7, 9, 2, 2, 66, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 17, 3, 2, 2, 2, 68, 71, 5, 20, 11, 2, 69, 71, 5, 22, 12, 2, 70, 68, 3, 2, 2, 2, 70, 69, 3, 2, 2, 2, 71, 19, 3, 2, 2, 2, 72, 73, 7, 10, 2, 2, 73, 21, 3, 2, 2, 2, 74, 77, 7, 11, 2, 2, 75, 76, 7, 3, 2, 2, 76, 78, 7, 9, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 23, 3, 2, 2, 2, 79, 81, 7, 4, 2, 2, 80, 79, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 25, 3, 2, 2, 2, 82, 83, 9, 2, 2, 2, 83, 27, 3, 2, 2, 2, 84, 85, 7, 9, 2, 2, 85, 29, 3, 2, 2, 2, 86, 87, 7, 14, 2, 2, 87, 31, 3, 2, 2, 2, 11, 37, 39, 48, 50, 59, 66, 70, 77, 80] \ No newline at end of file diff --git a/HybroGen/RegisterDescription.tokens b/HybroGen/RegisterDescription.tokens new file mode 100644 index 0000000..7db056c --- /dev/null +++ b/HybroGen/RegisterDescription.tokens @@ -0,0 +1,16 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +WS=5 +COMMENT=6 +INT=7 +FUNCNAME=8 +REGWN=9 +NEWLINE=10 +PREFIX=11 +NAME=12 +'-'=1 +'v'=2 +'i'=3 +'f'=4 diff --git a/HybroGen/RegisterDescriptionLexer.interp b/HybroGen/RegisterDescriptionLexer.interp new file mode 100644 index 0000000..29a9957 --- /dev/null +++ b/HybroGen/RegisterDescriptionLexer.interp @@ -0,0 +1,53 @@ +token literal names: +null +'-' +'v' +'i' +'f' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +WS +COMMENT +INT +FUNCNAME +REGWN +NEWLINE +PREFIX +NAME + +rule names: +T__0 +T__1 +T__2 +T__3 +WS +COMMENT +INT +FUNCNAME +REGWN +NEWLINE +PREFIX +NAME + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 14, 96, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 6, 6, 37, 10, 6, 13, 6, 14, 6, 38, 3, 6, 3, 6, 3, 7, 3, 7, 7, 7, 45, 10, 7, 12, 7, 14, 7, 48, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 6, 8, 55, 10, 8, 13, 8, 14, 8, 56, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 71, 10, 9, 3, 10, 3, 10, 3, 10, 3, 11, 5, 11, 77, 10, 11, 3, 11, 3, 11, 3, 12, 3, 12, 7, 12, 83, 10, 12, 12, 12, 14, 12, 86, 11, 12, 3, 12, 3, 12, 3, 13, 3, 13, 7, 13, 92, 10, 13, 12, 13, 14, 13, 95, 11, 13, 3, 46, 2, 14, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 3, 2, 7, 4, 2, 11, 11, 34, 34, 3, 2, 50, 59, 5, 2, 75, 75, 81, 81, 86, 86, 4, 2, 67, 92, 99, 124, 7, 2, 48, 48, 50, 59, 67, 92, 97, 97, 99, 124, 2, 107, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 3, 27, 3, 2, 2, 2, 5, 29, 3, 2, 2, 2, 7, 31, 3, 2, 2, 2, 9, 33, 3, 2, 2, 2, 11, 36, 3, 2, 2, 2, 13, 42, 3, 2, 2, 2, 15, 54, 3, 2, 2, 2, 17, 70, 3, 2, 2, 2, 19, 72, 3, 2, 2, 2, 21, 76, 3, 2, 2, 2, 23, 80, 3, 2, 2, 2, 25, 89, 3, 2, 2, 2, 27, 28, 7, 47, 2, 2, 28, 4, 3, 2, 2, 2, 29, 30, 7, 120, 2, 2, 30, 6, 3, 2, 2, 2, 31, 32, 7, 107, 2, 2, 32, 8, 3, 2, 2, 2, 33, 34, 7, 104, 2, 2, 34, 10, 3, 2, 2, 2, 35, 37, 9, 2, 2, 2, 36, 35, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 36, 3, 2, 2, 2, 38, 39, 3, 2, 2, 2, 39, 40, 3, 2, 2, 2, 40, 41, 8, 6, 2, 2, 41, 12, 3, 2, 2, 2, 42, 46, 7, 37, 2, 2, 43, 45, 11, 2, 2, 2, 44, 43, 3, 2, 2, 2, 45, 48, 3, 2, 2, 2, 46, 47, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 47, 49, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 49, 50, 5, 21, 11, 2, 50, 51, 3, 2, 2, 2, 51, 52, 8, 7, 2, 2, 52, 14, 3, 2, 2, 2, 53, 55, 9, 3, 2, 2, 54, 53, 3, 2, 2, 2, 55, 56, 3, 2, 2, 2, 56, 54, 3, 2, 2, 2, 56, 57, 3, 2, 2, 2, 57, 16, 3, 2, 2, 2, 58, 71, 7, 92, 2, 2, 59, 60, 7, 84, 2, 2, 60, 71, 7, 67, 2, 2, 61, 62, 7, 72, 2, 2, 62, 71, 7, 82, 2, 2, 63, 64, 7, 85, 2, 2, 64, 71, 7, 82, 2, 2, 65, 66, 7, 73, 2, 2, 66, 71, 7, 82, 2, 2, 67, 68, 7, 86, 2, 2, 68, 71, 7, 82, 2, 2, 69, 71, 7, 90, 2, 2, 70, 58, 3, 2, 2, 2, 70, 59, 3, 2, 2, 2, 70, 61, 3, 2, 2, 2, 70, 63, 3, 2, 2, 2, 70, 65, 3, 2, 2, 2, 70, 67, 3, 2, 2, 2, 70, 69, 3, 2, 2, 2, 71, 18, 3, 2, 2, 2, 72, 73, 9, 4, 2, 2, 73, 74, 5, 15, 8, 2, 74, 20, 3, 2, 2, 2, 75, 77, 7, 15, 2, 2, 76, 75, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 7, 12, 2, 2, 79, 22, 3, 2, 2, 2, 80, 84, 7, 38, 2, 2, 81, 83, 9, 5, 2, 2, 82, 81, 3, 2, 2, 2, 83, 86, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 85, 3, 2, 2, 2, 85, 87, 3, 2, 2, 2, 86, 84, 3, 2, 2, 2, 87, 88, 5, 15, 8, 2, 88, 24, 3, 2, 2, 2, 89, 93, 9, 5, 2, 2, 90, 92, 9, 6, 2, 2, 91, 90, 3, 2, 2, 2, 92, 95, 3, 2, 2, 2, 93, 91, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 26, 3, 2, 2, 2, 95, 93, 3, 2, 2, 2, 10, 2, 38, 46, 56, 70, 76, 84, 93, 3, 8, 2, 2] \ No newline at end of file diff --git a/HybroGen/RegisterDescriptionLexer.py b/HybroGen/RegisterDescriptionLexer.py new file mode 100644 index 0000000..7915d78 --- /dev/null +++ b/HybroGen/RegisterDescriptionLexer.py @@ -0,0 +1,92 @@ +# Generated from RegisterDescription.g4 by ANTLR 4.9.2 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + + +def serializedATN(): + with StringIO() as buf: + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\16") + buf.write("`\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") + buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\3\2") + buf.write("\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\6\6%\n\6\r\6\16\6&\3") + buf.write("\6\3\6\3\7\3\7\7\7-\n\7\f\7\16\7\60\13\7\3\7\3\7\3\7\3") + buf.write("\7\3\b\6\b\67\n\b\r\b\16\b8\3\t\3\t\3\t\3\t\3\t\3\t\3") + buf.write("\t\3\t\3\t\3\t\3\t\3\t\5\tG\n\t\3\n\3\n\3\n\3\13\5\13") + buf.write("M\n\13\3\13\3\13\3\f\3\f\7\fS\n\f\f\f\16\fV\13\f\3\f\3") + buf.write("\f\3\r\3\r\7\r\\\n\r\f\r\16\r_\13\r\3.\2\16\3\3\5\4\7") + buf.write("\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\3\2\7") + buf.write("\4\2\13\13\"\"\3\2\62;\5\2KKQQVV\4\2C\\c|\7\2\60\60\62") + buf.write(";C\\aac|\2k\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3") + buf.write("\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2") + buf.write("\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2") + buf.write("\2\3\33\3\2\2\2\5\35\3\2\2\2\7\37\3\2\2\2\t!\3\2\2\2\13") + buf.write("$\3\2\2\2\r*\3\2\2\2\17\66\3\2\2\2\21F\3\2\2\2\23H\3\2") + buf.write("\2\2\25L\3\2\2\2\27P\3\2\2\2\31Y\3\2\2\2\33\34\7/\2\2") + buf.write("\34\4\3\2\2\2\35\36\7x\2\2\36\6\3\2\2\2\37 \7k\2\2 \b") + buf.write("\3\2\2\2!\"\7h\2\2\"\n\3\2\2\2#%\t\2\2\2$#\3\2\2\2%&\3") + buf.write("\2\2\2&$\3\2\2\2&\'\3\2\2\2\'(\3\2\2\2()\b\6\2\2)\f\3") + buf.write("\2\2\2*.\7%\2\2+-\13\2\2\2,+\3\2\2\2-\60\3\2\2\2./\3\2") + buf.write("\2\2.,\3\2\2\2/\61\3\2\2\2\60.\3\2\2\2\61\62\5\25\13\2") + buf.write("\62\63\3\2\2\2\63\64\b\7\2\2\64\16\3\2\2\2\65\67\t\3\2") + buf.write("\2\66\65\3\2\2\2\678\3\2\2\28\66\3\2\2\289\3\2\2\29\20") + buf.write("\3\2\2\2:G\7\\\2\2;<\7T\2\2\7H\2\2>G\7R\2\2") + buf.write("?@\7U\2\2@G\7R\2\2AB\7I\2\2BG\7R\2\2CD\7V\2\2DG\7R\2\2") + buf.write("EG\7Z\2\2F:\3\2\2\2F;\3\2\2\2F=\3\2\2\2F?\3\2\2\2FA\3") + buf.write("\2\2\2FC\3\2\2\2FE\3\2\2\2G\22\3\2\2\2HI\t\4\2\2IJ\5\17") + buf.write("\b\2J\24\3\2\2\2KM\7\17\2\2LK\3\2\2\2LM\3\2\2\2MN\3\2") + buf.write("\2\2NO\7\f\2\2O\26\3\2\2\2PT\7&\2\2QS\t\5\2\2RQ\3\2\2") + buf.write("\2SV\3\2\2\2TR\3\2\2\2TU\3\2\2\2UW\3\2\2\2VT\3\2\2\2W") + buf.write("X\5\17\b\2X\30\3\2\2\2Y]\t\5\2\2Z\\\t\6\2\2[Z\3\2\2\2") + buf.write("\\_\3\2\2\2][\3\2\2\2]^\3\2\2\2^\32\3\2\2\2_]\3\2\2\2") + buf.write("\n\2&.8FLT]\3\b\2\2") + return buf.getvalue() + + +class RegisterDescriptionLexer(Lexer): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + T__0 = 1 + T__1 = 2 + T__2 = 3 + T__3 = 4 + WS = 5 + COMMENT = 6 + INT = 7 + FUNCNAME = 8 + REGWN = 9 + NEWLINE = 10 + PREFIX = 11 + NAME = 12 + + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + + modeNames = [ "DEFAULT_MODE" ] + + literalNames = [ "", + "'-'", "'v'", "'i'", "'f'" ] + + symbolicNames = [ "", + "WS", "COMMENT", "INT", "FUNCNAME", "REGWN", "NEWLINE", "PREFIX", + "NAME" ] + + ruleNames = [ "T__0", "T__1", "T__2", "T__3", "WS", "COMMENT", "INT", + "FUNCNAME", "REGWN", "NEWLINE", "PREFIX", "NAME" ] + + grammarFileName = "RegisterDescription.g4" + + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.9.2") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + diff --git a/HybroGen/RegisterDescriptionLexer.tokens b/HybroGen/RegisterDescriptionLexer.tokens new file mode 100644 index 0000000..7db056c --- /dev/null +++ b/HybroGen/RegisterDescriptionLexer.tokens @@ -0,0 +1,16 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +WS=5 +COMMENT=6 +INT=7 +FUNCNAME=8 +REGWN=9 +NEWLINE=10 +PREFIX=11 +NAME=12 +'-'=1 +'v'=2 +'i'=3 +'f'=4 diff --git a/HybroGen/RegisterDescriptionListener.py b/HybroGen/RegisterDescriptionListener.py new file mode 100644 index 0000000..dcd9a40 --- /dev/null +++ b/HybroGen/RegisterDescriptionListener.py @@ -0,0 +1,147 @@ +# Generated from RegisterDescription.g4 by ANTLR 4.9.2 +from antlr4 import * +if __name__ is not None and "." in __name__: + from .RegisterDescriptionParser import RegisterDescriptionParser +else: + from RegisterDescriptionParser import RegisterDescriptionParser + +# This class defines a complete listener for a parse tree produced by RegisterDescriptionParser. +class RegisterDescriptionListener(ParseTreeListener): + + # Enter a parse tree produced by RegisterDescriptionParser#registerdescription. + def enterRegisterdescription(self, ctx:RegisterDescriptionParser.RegisterdescriptionContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerdescription. + def exitRegisterdescription(self, ctx:RegisterDescriptionParser.RegisterdescriptionContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#headerlines. + def enterHeaderlines(self, ctx:RegisterDescriptionParser.HeaderlinesContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#headerlines. + def exitHeaderlines(self, ctx:RegisterDescriptionParser.HeaderlinesContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#commentline. + def enterCommentline(self, ctx:RegisterDescriptionParser.CommentlineContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#commentline. + def exitCommentline(self, ctx:RegisterDescriptionParser.CommentlineContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#emptyline. + def enterEmptyline(self, ctx:RegisterDescriptionParser.EmptylineContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#emptyline. + def exitEmptyline(self, ctx:RegisterDescriptionParser.EmptylineContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerlines. + def enterRegisterlines(self, ctx:RegisterDescriptionParser.RegisterlinesContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerlines. + def exitRegisterlines(self, ctx:RegisterDescriptionParser.RegisterlinesContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerline. + def enterRegisterline(self, ctx:RegisterDescriptionParser.RegisterlineContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerline. + def exitRegisterline(self, ctx:RegisterDescriptionParser.RegisterlineContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerlist. + def enterRegisterlist(self, ctx:RegisterDescriptionParser.RegisterlistContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerlist. + def exitRegisterlist(self, ctx:RegisterDescriptionParser.RegisterlistContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerprefix. + def enterRegisterprefix(self, ctx:RegisterDescriptionParser.RegisterprefixContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerprefix. + def exitRegisterprefix(self, ctx:RegisterDescriptionParser.RegisterprefixContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerfunctionlist. + def enterRegisterfunctionlist(self, ctx:RegisterDescriptionParser.RegisterfunctionlistContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerfunctionlist. + def exitRegisterfunctionlist(self, ctx:RegisterDescriptionParser.RegisterfunctionlistContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerfunction. + def enterRegisterfunction(self, ctx:RegisterDescriptionParser.RegisterfunctionContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerfunction. + def exitRegisterfunction(self, ctx:RegisterDescriptionParser.RegisterfunctionContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerfunctionwn. + def enterRegisterfunctionwn(self, ctx:RegisterDescriptionParser.RegisterfunctionwnContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerfunctionwn. + def exitRegisterfunctionwn(self, ctx:RegisterDescriptionParser.RegisterfunctionwnContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#regbankvec. + def enterRegbankvec(self, ctx:RegisterDescriptionParser.RegbankvecContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#regbankvec. + def exitRegbankvec(self, ctx:RegisterDescriptionParser.RegbankvecContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#regbank. + def enterRegbank(self, ctx:RegisterDescriptionParser.RegbankContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#regbank. + def exitRegbank(self, ctx:RegisterDescriptionParser.RegbankContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#registerwidth. + def enterRegisterwidth(self, ctx:RegisterDescriptionParser.RegisterwidthContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#registerwidth. + def exitRegisterwidth(self, ctx:RegisterDescriptionParser.RegisterwidthContext): + pass + + + # Enter a parse tree produced by RegisterDescriptionParser#extension. + def enterExtension(self, ctx:RegisterDescriptionParser.ExtensionContext): + pass + + # Exit a parse tree produced by RegisterDescriptionParser#extension. + def exitExtension(self, ctx:RegisterDescriptionParser.ExtensionContext): + pass + + + +del RegisterDescriptionParser \ No newline at end of file diff --git a/HybroGen/RegisterDescriptionParser.py b/HybroGen/RegisterDescriptionParser.py new file mode 100644 index 0000000..cde839d --- /dev/null +++ b/HybroGen/RegisterDescriptionParser.py @@ -0,0 +1,891 @@ +# Generated from RegisterDescription.g4 by ANTLR 4.9.2 +# encoding: utf-8 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + +def serializedATN(): + with StringIO() as buf: + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\16") + buf.write("Y\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b") + buf.write("\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t") + buf.write("\16\4\17\t\17\4\20\t\20\3\2\3\2\3\2\3\3\3\3\6\3&\n\3\r") + buf.write("\3\16\3\'\3\4\3\4\3\5\3\5\3\6\3\6\3\6\6\6\61\n\6\r\6\16") + buf.write("\6\62\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7<\n\7\3\b\3\b\3\t") + buf.write("\3\t\3\t\5\tC\n\t\3\n\3\n\5\nG\n\n\3\13\3\13\3\f\3\f\3") + buf.write("\f\5\fN\n\f\3\r\5\rQ\n\r\3\16\3\16\3\17\3\17\3\20\3\20") + buf.write("\3\20\2\2\21\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36\2") + buf.write("\3\3\2\5\6\2S\2 \3\2\2\2\4%\3\2\2\2\6)\3\2\2\2\b+\3\2") + buf.write("\2\2\n\60\3\2\2\2\f\64\3\2\2\2\16=\3\2\2\2\20?\3\2\2\2") + buf.write("\22F\3\2\2\2\24H\3\2\2\2\26J\3\2\2\2\30P\3\2\2\2\32R\3") + buf.write("\2\2\2\34T\3\2\2\2\36V\3\2\2\2 !\5\4\3\2!\"\5\n\6\2\"") + buf.write("\3\3\2\2\2#&\5\6\4\2$&\5\b\5\2%#\3\2\2\2%$\3\2\2\2&\'") + buf.write("\3\2\2\2\'%\3\2\2\2\'(\3\2\2\2(\5\3\2\2\2)*\7\b\2\2*\7") + buf.write("\3\2\2\2+,\7\f\2\2,\t\3\2\2\2-\61\5\6\4\2.\61\5\f\7\2") + buf.write("/\61\5\b\5\2\60-\3\2\2\2\60.\3\2\2\2\60/\3\2\2\2\61\62") + buf.write("\3\2\2\2\62\60\3\2\2\2\62\63\3\2\2\2\63\13\3\2\2\2\64") + buf.write("\65\5\36\20\2\65\66\5\30\r\2\66\67\5\32\16\2\678\5\16") + buf.write("\b\289\5\34\17\29;\5\22\n\2:<\7\f\2\2;:\3\2\2\2;<\3\2") + buf.write("\2\2<\r\3\2\2\2=>\5\20\t\2>\17\3\2\2\2?B\7\r\2\2@A\7\3") + buf.write("\2\2AC\7\t\2\2B@\3\2\2\2BC\3\2\2\2C\21\3\2\2\2DG\5\24") + buf.write("\13\2EG\5\26\f\2FD\3\2\2\2FE\3\2\2\2G\23\3\2\2\2HI\7\n") + buf.write("\2\2I\25\3\2\2\2JM\7\13\2\2KL\7\3\2\2LN\7\t\2\2MK\3\2") + buf.write("\2\2MN\3\2\2\2N\27\3\2\2\2OQ\7\4\2\2PO\3\2\2\2PQ\3\2\2") + buf.write("\2Q\31\3\2\2\2RS\t\2\2\2S\33\3\2\2\2TU\7\t\2\2U\35\3\2") + buf.write("\2\2VW\7\16\2\2W\37\3\2\2\2\13%\'\60\62;BFMP") + return buf.getvalue() + + +class RegisterDescriptionParser ( Parser ): + + grammarFileName = "RegisterDescription.g4" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ "", "'-'", "'v'", "'i'", "'f'" ] + + symbolicNames = [ "", "", "", "", + "", "WS", "COMMENT", "INT", "FUNCNAME", "REGWN", + "NEWLINE", "PREFIX", "NAME" ] + + RULE_registerdescription = 0 + RULE_headerlines = 1 + RULE_commentline = 2 + RULE_emptyline = 3 + RULE_registerlines = 4 + RULE_registerline = 5 + RULE_registerlist = 6 + RULE_registerprefix = 7 + RULE_registerfunctionlist = 8 + RULE_registerfunction = 9 + RULE_registerfunctionwn = 10 + RULE_regbankvec = 11 + RULE_regbank = 12 + RULE_registerwidth = 13 + RULE_extension = 14 + + ruleNames = [ "registerdescription", "headerlines", "commentline", + "emptyline", "registerlines", "registerline", "registerlist", + "registerprefix", "registerfunctionlist", "registerfunction", + "registerfunctionwn", "regbankvec", "regbank", "registerwidth", + "extension" ] + + EOF = Token.EOF + T__0=1 + T__1=2 + T__2=3 + T__3=4 + WS=5 + COMMENT=6 + INT=7 + FUNCNAME=8 + REGWN=9 + NEWLINE=10 + PREFIX=11 + NAME=12 + + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.9.2") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + + + + class RegisterdescriptionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def headerlines(self): + return self.getTypedRuleContext(RegisterDescriptionParser.HeaderlinesContext,0) + + + def registerlines(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterlinesContext,0) + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerdescription + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterdescription" ): + listener.enterRegisterdescription(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterdescription" ): + listener.exitRegisterdescription(self) + + + + + def registerdescription(self): + + localctx = RegisterDescriptionParser.RegisterdescriptionContext(self, self._ctx, self.state) + self.enterRule(localctx, 0, self.RULE_registerdescription) + try: + self.enterOuterAlt(localctx, 1) + self.state = 30 + self.headerlines() + self.state = 31 + self.registerlines() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class HeaderlinesContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def commentline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(RegisterDescriptionParser.CommentlineContext) + else: + return self.getTypedRuleContext(RegisterDescriptionParser.CommentlineContext,i) + + + def emptyline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(RegisterDescriptionParser.EmptylineContext) + else: + return self.getTypedRuleContext(RegisterDescriptionParser.EmptylineContext,i) + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_headerlines + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterHeaderlines" ): + listener.enterHeaderlines(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitHeaderlines" ): + listener.exitHeaderlines(self) + + + + + def headerlines(self): + + localctx = RegisterDescriptionParser.HeaderlinesContext(self, self._ctx, self.state) + self.enterRule(localctx, 2, self.RULE_headerlines) + try: + self.enterOuterAlt(localctx, 1) + self.state = 35 + self._errHandler.sync(self) + _alt = 1 + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt == 1: + self.state = 35 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [RegisterDescriptionParser.COMMENT]: + self.state = 33 + self.commentline() + pass + elif token in [RegisterDescriptionParser.NEWLINE]: + self.state = 34 + self.emptyline() + pass + else: + raise NoViableAltException(self) + + + else: + raise NoViableAltException(self) + self.state = 37 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,1,self._ctx) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class CommentlineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def COMMENT(self): + return self.getToken(RegisterDescriptionParser.COMMENT, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_commentline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterCommentline" ): + listener.enterCommentline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitCommentline" ): + listener.exitCommentline(self) + + + + + def commentline(self): + + localctx = RegisterDescriptionParser.CommentlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 4, self.RULE_commentline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 39 + self.match(RegisterDescriptionParser.COMMENT) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class EmptylineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NEWLINE(self): + return self.getToken(RegisterDescriptionParser.NEWLINE, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_emptyline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterEmptyline" ): + listener.enterEmptyline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitEmptyline" ): + listener.exitEmptyline(self) + + + + + def emptyline(self): + + localctx = RegisterDescriptionParser.EmptylineContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_emptyline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 41 + self.match(RegisterDescriptionParser.NEWLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterlinesContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def commentline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(RegisterDescriptionParser.CommentlineContext) + else: + return self.getTypedRuleContext(RegisterDescriptionParser.CommentlineContext,i) + + + def registerline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(RegisterDescriptionParser.RegisterlineContext) + else: + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterlineContext,i) + + + def emptyline(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(RegisterDescriptionParser.EmptylineContext) + else: + return self.getTypedRuleContext(RegisterDescriptionParser.EmptylineContext,i) + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerlines + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterlines" ): + listener.enterRegisterlines(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterlines" ): + listener.exitRegisterlines(self) + + + + + def registerlines(self): + + localctx = RegisterDescriptionParser.RegisterlinesContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_registerlines) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 46 + self._errHandler.sync(self) + _la = self._input.LA(1) + while True: + self.state = 46 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [RegisterDescriptionParser.COMMENT]: + self.state = 43 + self.commentline() + pass + elif token in [RegisterDescriptionParser.NAME]: + self.state = 44 + self.registerline() + pass + elif token in [RegisterDescriptionParser.NEWLINE]: + self.state = 45 + self.emptyline() + pass + else: + raise NoViableAltException(self) + + self.state = 48 + self._errHandler.sync(self) + _la = self._input.LA(1) + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << RegisterDescriptionParser.COMMENT) | (1 << RegisterDescriptionParser.NEWLINE) | (1 << RegisterDescriptionParser.NAME))) != 0)): + break + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterlineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def extension(self): + return self.getTypedRuleContext(RegisterDescriptionParser.ExtensionContext,0) + + + def regbankvec(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegbankvecContext,0) + + + def regbank(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegbankContext,0) + + + def registerlist(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterlistContext,0) + + + def registerwidth(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterwidthContext,0) + + + def registerfunctionlist(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterfunctionlistContext,0) + + + def NEWLINE(self): + return self.getToken(RegisterDescriptionParser.NEWLINE, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerline + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterline" ): + listener.enterRegisterline(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterline" ): + listener.exitRegisterline(self) + + + + + def registerline(self): + + localctx = RegisterDescriptionParser.RegisterlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_registerline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 50 + self.extension() + self.state = 51 + self.regbankvec() + self.state = 52 + self.regbank() + self.state = 53 + self.registerlist() + self.state = 54 + self.registerwidth() + self.state = 55 + self.registerfunctionlist() + self.state = 57 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,4,self._ctx) + if la_ == 1: + self.state = 56 + self.match(RegisterDescriptionParser.NEWLINE) + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterlistContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def registerprefix(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterprefixContext,0) + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerlist + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterlist" ): + listener.enterRegisterlist(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterlist" ): + listener.exitRegisterlist(self) + + + + + def registerlist(self): + + localctx = RegisterDescriptionParser.RegisterlistContext(self, self._ctx, self.state) + self.enterRule(localctx, 12, self.RULE_registerlist) + try: + self.enterOuterAlt(localctx, 1) + self.state = 59 + self.registerprefix() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterprefixContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def PREFIX(self): + return self.getToken(RegisterDescriptionParser.PREFIX, 0) + + def INT(self): + return self.getToken(RegisterDescriptionParser.INT, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerprefix + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterprefix" ): + listener.enterRegisterprefix(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterprefix" ): + listener.exitRegisterprefix(self) + + + + + def registerprefix(self): + + localctx = RegisterDescriptionParser.RegisterprefixContext(self, self._ctx, self.state) + self.enterRule(localctx, 14, self.RULE_registerprefix) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 61 + self.match(RegisterDescriptionParser.PREFIX) + self.state = 64 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==RegisterDescriptionParser.T__0: + self.state = 62 + self.match(RegisterDescriptionParser.T__0) + self.state = 63 + self.match(RegisterDescriptionParser.INT) + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterfunctionlistContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def registerfunction(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterfunctionContext,0) + + + def registerfunctionwn(self): + return self.getTypedRuleContext(RegisterDescriptionParser.RegisterfunctionwnContext,0) + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerfunctionlist + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterfunctionlist" ): + listener.enterRegisterfunctionlist(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterfunctionlist" ): + listener.exitRegisterfunctionlist(self) + + + + + def registerfunctionlist(self): + + localctx = RegisterDescriptionParser.RegisterfunctionlistContext(self, self._ctx, self.state) + self.enterRule(localctx, 16, self.RULE_registerfunctionlist) + try: + self.state = 68 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [RegisterDescriptionParser.FUNCNAME]: + self.enterOuterAlt(localctx, 1) + self.state = 66 + self.registerfunction() + pass + elif token in [RegisterDescriptionParser.REGWN]: + self.enterOuterAlt(localctx, 2) + self.state = 67 + self.registerfunctionwn() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterfunctionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def FUNCNAME(self): + return self.getToken(RegisterDescriptionParser.FUNCNAME, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerfunction + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterfunction" ): + listener.enterRegisterfunction(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterfunction" ): + listener.exitRegisterfunction(self) + + + + + def registerfunction(self): + + localctx = RegisterDescriptionParser.RegisterfunctionContext(self, self._ctx, self.state) + self.enterRule(localctx, 18, self.RULE_registerfunction) + try: + self.enterOuterAlt(localctx, 1) + self.state = 70 + self.match(RegisterDescriptionParser.FUNCNAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterfunctionwnContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def REGWN(self): + return self.getToken(RegisterDescriptionParser.REGWN, 0) + + def INT(self): + return self.getToken(RegisterDescriptionParser.INT, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerfunctionwn + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterfunctionwn" ): + listener.enterRegisterfunctionwn(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterfunctionwn" ): + listener.exitRegisterfunctionwn(self) + + + + + def registerfunctionwn(self): + + localctx = RegisterDescriptionParser.RegisterfunctionwnContext(self, self._ctx, self.state) + self.enterRule(localctx, 20, self.RULE_registerfunctionwn) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 72 + self.match(RegisterDescriptionParser.REGWN) + self.state = 75 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==RegisterDescriptionParser.T__0: + self.state = 73 + self.match(RegisterDescriptionParser.T__0) + self.state = 74 + self.match(RegisterDescriptionParser.INT) + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegbankvecContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_regbankvec + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegbankvec" ): + listener.enterRegbankvec(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegbankvec" ): + listener.exitRegbankvec(self) + + + + + def regbankvec(self): + + localctx = RegisterDescriptionParser.RegbankvecContext(self, self._ctx, self.state) + self.enterRule(localctx, 22, self.RULE_regbankvec) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 78 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==RegisterDescriptionParser.T__1: + self.state = 77 + self.match(RegisterDescriptionParser.T__1) + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegbankContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_regbank + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegbank" ): + listener.enterRegbank(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegbank" ): + listener.exitRegbank(self) + + + + + def regbank(self): + + localctx = RegisterDescriptionParser.RegbankContext(self, self._ctx, self.state) + self.enterRule(localctx, 24, self.RULE_regbank) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 80 + _la = self._input.LA(1) + if not(_la==RegisterDescriptionParser.T__2 or _la==RegisterDescriptionParser.T__3): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class RegisterwidthContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def INT(self): + return self.getToken(RegisterDescriptionParser.INT, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_registerwidth + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterRegisterwidth" ): + listener.enterRegisterwidth(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitRegisterwidth" ): + listener.exitRegisterwidth(self) + + + + + def registerwidth(self): + + localctx = RegisterDescriptionParser.RegisterwidthContext(self, self._ctx, self.state) + self.enterRule(localctx, 26, self.RULE_registerwidth) + try: + self.enterOuterAlt(localctx, 1) + self.state = 82 + self.match(RegisterDescriptionParser.INT) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ExtensionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(RegisterDescriptionParser.NAME, 0) + + def getRuleIndex(self): + return RegisterDescriptionParser.RULE_extension + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterExtension" ): + listener.enterExtension(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitExtension" ): + listener.exitExtension(self) + + + + + def extension(self): + + localctx = RegisterDescriptionParser.ExtensionContext(self, self._ctx, self.state) + self.enterRule(localctx, 28, self.RULE_extension) + try: + self.enterOuterAlt(localctx, 1) + self.state = 84 + self.match(RegisterDescriptionParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + + + diff --git a/HybroGen/__pycache__/Counter.cpython-312.pyc b/HybroGen/__pycache__/Counter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7414827b330a94b0c4c0372ca47f14815241fbdb GIT binary patch literal 1673 zcmcIj&2Jk;6o0cjYdeX9DyX8sfmXS2;UD12g|r8fJw@uNw-6tYdg9HlEz>G32ikY|?VEXT z-pB8~{e5(F7*Kw_^{1oj01womFSMt0D+C|{4bA|E4d7%;OD$CpgllWB0?2C`2-xa9 zsA@u6&Gy3#zFgnJNJVrG=h_BTDc2DVP7yPKVP@j&yUmvC3mHx&3Tv*ciki<_p5uPPY{s3M?=)T4mI15v zqpMtMHaJP>9zlq}fi_sEr4kTR3n!Oc$9L?y6AI>E6#ovjY?7FA+qc!%6ZMZh6`DP& zOkZp^M7>$F>(iGTr{1j0%$%A&8?4CY8Q~6;UdgXt3gVn)Ihe+>!m<8s|Hi<-bO%r@-KDB zPH{Y%*qn$;o2C23sRJNGCp!x}`OzQA?U|ovf0(`V!B2C46f4{L%JqeP9j$wXu})5^ zFty%~ifT%ys-XKVLWB(-PRFwdT?feyf7K?6L{37)r+LhwEx?t3w%ydjh#X|v&o+Oy8~ls+_ew7h4hg5rW>zh?N@-c~ zuw^xxyj53v-m)&Y?0V0F^X1K&Wyu_7m17EyA>4%|O0ok|jUxf2c*?v1yY#gKO*6(1 za)wdt<_&|T50r~a+^`)Nlj#eKi?M$G!aK2k?!tS^rjZ64S6;+UQpHBHt5Qv7kn~Y* zF0FW8GBhYQy#N7MhmgNBMZ*39g#A~5<~!j%ePTCP_;UE_!VWdAo&M}}=Z%eX|6kpu QL!GJ5&+Z=uI+>LA51*q=asU7T literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/GenGeneratorFromDb.cpython-312.pyc b/HybroGen/__pycache__/GenGeneratorFromDb.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72ae7eb43f8c1dff6f4d23513147c601ead43478 GIT binary patch literal 18476 zcmd6PYfxKPn&7=x4L9>SQ1unh*siC;Lzyko%FU}F>8MCb|-MiRafFCit~ z+TL9`O*)Y7T0Y)of=)sZmDmjt6aPNr~hoRIJ>F# zRBi3|ovSMeEN419(^GqG&N=ryzVn^$Jigbt`jt+nq2T$K|L3>vxx*Co-|zHF2AF71QPNtuipzXUF#I9ieVBW z_4r@I`%TJ4Ax1+COMizNlCcbga#jYRf|Wz4L_CIaSS5sj0ff-^kcL$c<+2)h)3Uh` z>R9bi9;+MDvw1`LtbWMA<_{IHhM_{XV93Z8LJbpZgs_M;L1<=+AhfVn*8ClM$U1Ma z?+^+)TweI^;v4}V*UtGots_ol2HH80mcifSAsF{fDv%sKMTO)nZG{4enPe8mA!CyU~ibFhLb5wPh{dGR-h)-$wWr6b5Cdvnm&-2hAO_i+J1<=~v-1g3&@jZBXTc{46<#OHUNbU3fNysVIu zd>3+Da{2o?J>#unl5AA>MxyJg=`4P?st1O*(dezlU%?qmGVYk;E7#GKk2>K9__#IMNh0?C?a3X`LfWmV!UNuHLumIcf<;x zgFIDYXW6YotB2w{5Ar(?#&*6Ckv~vb5-M$6W#LtpxT=I#l{`?DB`h|mtxK4!H;0xH zm?mM~88_GR=302sCd{QIDlCe~-%vdUj3{U3s>X@JzsJu(a1&QC#M>WE8%VEnI^%Sq zU{%n)c7`j0CW2y$b9)2uhI>npdHiF3?8;{2N=Wel=Wx1$mMml=B_^ok$KX1Z$ko4j z?Db<`Y7I*V-Z-@(qqG*T3`(}3jtiTh{@-95!%>Rc0kXu0Wx}wSvu$8jMvh8Fh+*YH z*kDkPVHK=$%f`>Lm8D_7O|v;$>SmHN*?UG^)w_yOM(ih$+KLmYEhpideY5`qE%fQu zQYw%-1hQ>*R!xq*dqNXY{@4dj7CK#rwsuEcJ_3OGn`mu-8b zgDI>GQFC;*WfW2(9h^*hmH-kWwC#}~(bQt69G2uWpivV$w>5-UsqOZj#wb?%@9A*P z7!_89a$uY|^XiZ~M9{j}64Z43td;W(Q0mjIrPQ~D!s@oKR2ZiOEF%A8*_ja8J7SIp;Wsr*1r$3mHzI z$K&(Diws_#(EEZ+-8hHmSg;_?|J+{ZhPq~D=QJ4n*fUirWtDs2|xYf-G^r)bAdtuP+P)Crnj(|fj zP5JzO_sHZt;xynp>1t+K7c1ycdP=<#(h50#mq(PI9Gn{o1n(#f2{~A~)ivtJV?h*u zq)=qaIzSu{>~IBIe5@;IgF&RmA&P5tTWa8O?azUw0!+H-MG!4=6V{!Pyo5IY&CVO0 zD>?VIWeM$$XlWy_ZH)9LR7I;zeAxPh7x=rmFXsNXDO!6mx?_k} z4Mp;PXENU$TpqkRygdA)vp*huZ!lhYkgq)WGv~+SAC2F+_R-Z?<;j?-CE9v{H(iKm z5{9x(N}(=|H2=<0yfU;-uU=X|5VO=rx)O!OH;*qLj}=x#S`ndBub*0Zj@OpGaVnuT zy?Oe^>4(~qja+EDp{3NiH*;UlT?*WMb@|npxtdp1zmdBs&ne#-Rh4YyQ!pl7!cetI zG3u&FbE43=qPt&MnaD3$D_=A6`IXDM4Fwc!C@GT}h@egsSqLpk_h6HX8@-W^rE>&_ z8>iyhQeIoS61X+DIu|c{o-cd;_Uv6ntgQWkwganlz23D_y<+9HyS~?jP%8jx+1^b` zuC5Z{JSy68b9{L`UbK%d+P6M-dpcIs6d_GdrJ&C~&{h**H@f25VqROkGWbwixuFIi zU*%CI>pO)j1Gg@&UVOVWW~?C?tF$5o;^s!)+!!-I$E%)uBNqfrDZ7R@*Tg`ORMn=k zqvjL5>IA&%3*TJ0u@F`55XG{TbO@^hbs8d;?T19BHUZWsd=SxtzvZ#tetw^xM%$uU${S}Z-}ZIo|ZDPJ2IS?Ac0aQ$cxBTL6t&@ ziDiN?V91k+awW(Td1=XV(FnXOrCNgGm`uY!6}{xZ{XL$#0^Pv%L(C08V3#MyJmZ+0 zb_w*1Ks)^);o_i^qs|*~!wJyon(GgM#61=)&o=ZeRZc;B{}Bja+iGAx#Jp&(a-4 z4LnSzH3$|67z9z6m1WL-7{u|3ls*gqlMk@NEW&t*{!k$aq(DriNK9@B8WBncM}XIK zd2Jq-$H&dv;1mpS)8x3e!Eq*95|C3?u&zh15fFD%$< zYsMRg9e&U7lylD>yRFG4mK+U-H5y=lz;K-7f`T-Hc{5=5=O7T2qdv~#2oT04En<~x z(&a%lSde>Q!ERZ|+)-$ibqNEyBIm*d;=cd^OktrpURc2wR;)Gig;fz1F6oA)@#Ujy zhUFJy`ih7=p`VHC!@NGcK~e3@OU&08^)vrdj3Dze<6@%vFerriqYS*OM;UQ~aZ;rR zxgwchBTURqkcq=!PzftQw^D{^mY7mnsU_y}9PEIcP!3CsDx3+XEOVJ8p+UJKQ~L<3 zyb37~WpY-Dr4Z*}OpXZ^9uq`LXF>|hxeB|5dk~V3QACF;3MpAN^oDzA+XGsfCd5FP z`>ujW^-2jcOJ98fpmc;onhf_X@t zx!9pj{<~`FG@vQ(iDzJAAlMZAi7?1XV-QjRhNu&Pb{Arhx^R;H51?=1L~eS_QYs{u zS|(|$WQ}41fukJ)D4K7zqm-<;K6P7ZzKz;> zAsMW9^Se38wSpKBj2Dl9hMLBhS*-e2y=ULQ$sH5GvzRn?qIe`d~5 zYIgvY)l1Cc0${EL#$yo~k3b13m)GfIfg1}sKJVl_aA-k}A~|;+u;2zUz!UrltrnQ! zjwf_YP*zh@6O`MIAGZbNc3YJ#sIc3P9kV^5?Lh`gWRUfQ4ngiw+a(PaVok<=G^n(b zEW4UROA6sJ+zCt}ciUQ^BN^ov0f4^^ z*b4A5Lt#V-0!KuV(B`2~Qm}Mnx#TfbON4HaN35@h5|-k)We;!Jv);Tu`hHi;^8B*m zkp)butLi01!n$MSh1DHvj&;R*qUE%w# zL|<`4N8J1?6VXXe)a&Ob0}uPAAIt`UV}cZjjI)F3Mz$KFyYcNbb3uH&!2B-?j5QZA zvtkHeOfNH!#9n?neTV(I_Y?0uN3?J7i;3va%h5{?erV+3apwcqc+`C@8kpzZ^UyL( zwF6L3b3Dk!CT|fu0A9uzIcPEUdmBL$=Rm)mc%xdS2b{HgN zS(keuQBt6pU2j(9vyb7qDV7d^Q9_AcI7nsY4Xpb13V6Gs(A$l0g zs$anutAlwY_VVe$ySx8O-7o5*XZxcAFY{+FMXwA;UvcqQMjxIWd*GgodS;;20^Nd* z+nG}cc!4I77pM%dCg>glxEBdwJq>itI&9-|mo#i+30T(8@w*y%b;aFl z_qu-ZYV_g|-#+y4w&6&vgu=ysRPS|IwOVl~cAO z5~NGsU3+aQ85%mO03FUfssRCdi!ndt!`lzSTvE--Y6ufOd0|>YA`x8ousX)hEBBHB4)JmRHLN9Qj^i!lq zrg- ztJ?+zqeAbZ)M92luhP!lM~+n>;TxgMx%mkSD# z2`(_)cW5j0Z~-jI%}@&E6Mi2s7|^>Zh%4_tB_5=|(;9W>nD3;U_PtG8>Q>vS*Y z#L_7&HIdSu=9aUkGb-3M8SH!pD}02o59K~?EL9!-vem=S3vE%PCX*Le7lNTShPZ~Tv*ku8^ALeE8G)N0lNq8 zZ!C(alZ=0pqSgDs5TPwta;)SmPpmbpoqO*PU$kf4!57u@+WH&q8#1W!JA>)wj^!OI z%`5KJ?wG-j?QGc2lr(*vd8jSJnzlyqipR`+se0 zSSw#Tzta5u3sGZ3qzwWvjw~7Dh8o^b6F1cJhWb17ojsrAMf>{WeHZw?3(<>LVtvEW zad&jW&yNRyL7iaQnW&-uF+~-0Ag9uGFp*}k;Njs6j!Ru0!rQ|e_QVa1yrJ<<`JGdr z0P8y!KRd*q9g4op#?HE;USD)-p7)|y(GK!N)X<3VdI-E8fCsjji0TiUYRc3|9NC{0 zYFi8C&P**kWp*2YnIH!!_(LZkz5Ris3cR&w#e#Cw?zcT@D;3$?^r8j*NFeJn!RNAW zGRNek&FgZ3ZQAAs`FC>bma_%xfP?fuT>uNz0j3$US7AMgHW@ITSdq0r4yxL=er0 z5$77~&UM2&D|htkTTM9GL5|_lZb(o#5sh{L7jS4gU6tI)K*io&=;-~v2JRzRfAD5 zTn(C8m5mgTVH|6+EzC}WU?t^}Q9IIJ%Rs?va!bp716`1C{ zHt6UmsSyr4GxuOh4Eo=&w~56~hHON9ve~(^nN0tI7TCwO=bP^th$dW#DN8X}z5z;D zuEy(CG7vz(OiOYUX}behfaH>0>>!F_vXF8jWs687@j)^vda=VYxcUbFq?R;A`T#)= z>uAbpa|8PfJZ`;|f zmO9*{u-!Q@+fl(?_4T%1pJ?ZHJ8eE}3pcTFr;|Ng>DLHK5rjYw2USw*piOM(pK>|f zquE+Mq3fT}8oP>XgnqaK7~pZr9mL>y48XEVabQTIxWf?Gb3_3JWh8C~1cC}N#gkBw zpY{3R-WU2r(NoEFLa`s0Chi+}M8ksF!LnrV$pIh@&_x=oh2txEf=PD*>z+~fFA%bd zh$bj)fVJH4=Io8xH($H)+B@8>+11&2Sv_A?|1;Ugs*hB63?Jpj%8teKP0{0nynZku z-(ZyLmuR?D6)gtG9bbH$Hy@95f()`Ww^kT4RBlkTu6o^&$hWMVxpjW^{M#2+UgGns zmQ-KMpkPC#R9~QfW8V4G7e4Kb7Ps-{wr|sz%C|)HUz-sScJuceavG7*8o`EfH;1=& zMlD^uw(IrICts^bZ=}KBZzyQ&RcrjLtY?A$=Nd@W8l$Mq%>a$W)i&gg70Trg36fMe}&zT%3{al^fQY8D_s%WXm`MgvH zrJq-juu9)@NVY|nL%jnJwZ}h#`ONeHrgb(DJyQA=)J#6vH7)7D0j-BgYCZWVz+@O5 z;f89aHU@f7fgE*%l*3Je0Y?j+(M~4i6N9%3wl;wSMpW2IoD7ZG-bt1jqr>u$9B@XN zdE1lijwX1gQjn8dTx_33Ba_P021^MG2{#bfb`gOMG01X*Gb;wnhba@i)WhO#5ai^n zLV5@7N;yLe{(gqd@q!i!2Q>C!+BQUZCBhn_- zfWrf)Y}> z84hqgImY!N&D-?5DQ%TT2U#wgKY_O$w>=rNn;K!pdWL-h{!arK#({~7T72f}1&p&^ zF(ae63~jX`En9%(oG9PcF}zC5HAH_?Y0~9m4^&7HLMcp>`=Rm~b5@vj1!`F%V)UU& zno%hRc6uqK$(UU&Ta>wblbCoznxr#>UJL+bb?}!5GpL8Z{6J+2%WbV&smoWB7v2ov zf=~f#CVROqq|3VAEFlBZJdIl@FKa#PQ}y($=rGeS9)@0aB(Z++8U5^hs(to;il3^N zpX?`p(L*dpRno}QaaQ^(VNH}EU8S`FacT0s3}e=oZKa0tBw9dyGJ|Y+)_SRnejo1o zKqcZ5F3i3{LWL4c5Q1`&mhY^5}H1BD#H#odPiVKptQ5? z$x4Zg(>QDl8KGsCbC{f9#*BTMgIqgl%qvl(2m zcRAtP3ymn6fwGiwpF%7|;nKmmY$Fao*a653TtxG@0w71$bk(=l*VWb8_u6LRO8}yT z%@Ba75mwpU9*>K4qv?*QgsEQo+j@v$dAR-b*`DSBxZW5DxIlSw`)z@7(iH%gaH~r- z6E89vvze&hr@4OtRDjz>bZ^isnxawa?aZ`eL!~`XNnrZ+!=HFFCwN9p6vV#$DZSGM zN?&IqsGeQ@18rwTg%FC9>Ma!RYp~ljYIQ~)8p7d@A!x@n_M_yoN(yenH^Xhn0ymwv z748@y|3nY!KuSIabNmz9#=S}kGVKkZX%hoxFo$TVfK(Xjz;{86$17-v>Cgov_lt^! z2C66V2=2hNq=IiHg?QUjixnglKWKisI;iXC+Bg(Ng&bTKlW46JmjxujF$x-XklAaq zs|31FU>uyl_`L!%J1Hm-{!Evy81ZX?u*lh-=3DlNgX2q4@Di7u=xiL#r;KgdjsawYW4p+nQU4d-^+w zomNm`R!gz){bB>gXQ!r`EElx z9k#@x9%qH+c-rd%T1xk@`jcl$a4#&=)JjcXIn7@C3+T?@1FFMy>MJd|)_B|avE?I6 zyx|nzaOz%1tYP5SCFjs@?ehD(4m>hjZ*)Gg)J4tpkxo#pR*Z3LEpM%jTN`+5!yR+f+7PogM=d9L?a5?? zTP3R{D|%jA9qIhiv}5J)+L_g3F;fj#5_LzGXjBCUZe3Zu5-(}wOB!!Gq9u*7l0(tr z!+ieXWv~iEtw*TBHAXE5c&PL>qRQXE-aZ>|tYPel} z=eeIZebN*&b@8gMi0UgPrPW8~zk7V8`F?Im#z+8pyyhA$hTEWXU*_gzt)nx&IecR{ zS~B-QH=i&S;e}eX!{--(7v5C*nA)MPiL@n5J0k6m;Bx9qufKGA_s9GG)4tElUsOiT zeGjx}5^&|UJz+H8>|E~rtG2rb|FY-Tr7zvS7A@O<+Yl>jykGiK%ytjFhyzlwI7b|S~(!68k;P-=TXWn`ZK4!Y5U)8T$ zQHRg;h6RC9oJpQU%C@z^b2e$5ntzzxkd#d+jiSk`*&OftAEqd=X@OzIvur;Nc zwBNnP@9TVE>q<4*FhGAB1yo6Sym&ufygy$20$=>Xoq>DudxKx-qL;wSJHcPN8s*T_ zJx4dAq2EuRM5lHaLwwu4%tg%XVumo&$++Md*0;Eb@GW1`Iq&GaU>`7R5tvOcp zKh$j6Ve&R~up~APQCeNL-2)5fM)RY5V?4it&##E**Yf$bx2vQ1wXysoNu&DBlI0S( z0Uc@HzE>J>uNamFZeCfw5;xWIrrLE!)KnWY?dS9N!wpo}C=HLax~QQVw;Fgs3gdbk zueZhZ)x5rXec&gT-@kk}C)#&D%DSU7!T8K;{LE`G!jo|05ymwOmj>W%hVI#xqQ z{v~`@Ut<2S8K$Yy^YkA!k5gr*XmY7#-E>-|{hNI4Y28-ObS@k@#F}xJc&0&Xra@~4 zpC@R|3~0?V@I}*5hdlpi3x_O-C6 znNLaj@|2_xDSKX~6YtrQzHOX*U!;*(IkyUkaX-Z1Z46*5P@>oT9ZbE80g9L0zr*0) zVsI0K{{R78j7|w)qOgI|7knhMRoLSG92@*c42XzSh^Z+Iu3_+>F>qpV8-tG^5OhQ) z>LrpGh~U}`A?RbQbO(d9IP?j=Zk2YpPciT35cu(~g*04@MZu-)nSzUWD?8ZuZNwL` zjUJ8*{|E%vDR30;DBsTde`mD3Q}`|9ny0xqejw9L{}ZtB8*TW(OgFue_y5W9U(V~x zgpdhtHqPOAa%0;)YMj_{j5aWwo{YcW&R_W z`hRkl`LmqwaC{}5@7ca~NLj2!_Zm4H=*68$7rZQZD6OZ1d@c#oDJ>YZ=}F(LZPGR4 zn%v^~@r%242}TM|^@@Q*_U}raIeKRjoVYY|6$&F zbAEXqed{M^{8))N*AMcBgSTg6h8KD5i=uP=1pO#o^Tkv}yn1ol95Wogvzs>@=e5Vh z+ApSE@mo9&Xn&Hy-{ZZ2#6cK->t^~;WbPKf zdclaiIZ=S_20s#1VVQBvWSMK2i4kP_nOV&AGYgoB5oCs#*Dz|9wWH+R&2*p~o!^O} zx>H83hQQCO5LN@fR{}o~fw#kkhXu{>u*b(vPhwg-JbZ21F)5aC_`$fy=gwg20tVzZ zH+~2t-V6IznEDO|uVc`H!CzqT83u$O{sdFEG583BpJ71E4R8 zpfb==xpjk~N(Pyzyl7KyP#89=6i`?|nZ5M&?nF`d^`1o0^!46EQ4hYpe7zH@oBNsT zT^o$Tths)AQ)_^Js#oc{$t*lZ#(Y{$CvYRPX=* literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/Insn.cpython-312.pyc b/HybroGen/__pycache__/Insn.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e6decaf027fa7d14b4fbb7d65dbd498be56a58b GIT binary patch literal 8549 zcmb^$TW}NCb$7KZt>m?3{C;BD#$bWN!{L!QF9@&Tf=MuelmJ53T^oTdnO&J6RSrzc zhnrWpfgIm`y%zv?CUA);?Zh*#ZhGPyggt^WT_AX~o zPBBr=YYSN8@y?o^<-bDXHX}2qSi+p*2z$y#xa-U*p4b2iga>FR0ze0`0~Cn^pp%FI zUBn5njJNcqzPaPX$IIzS^%yktpMA|T7aHto7bcBheB#7_TfHxI2e*W{*Wga zQX|SlAQB9RJVt9mkv)Ab4_q5PL&1<=iF)KvAWVXxkscEr@{h@$?x5=TT$U9Trh0ok zsyyZoMS=kj63uaRgkK2)!Nm9jvZ~6&qsSvcH3E~ZB_|LILnG(MWLU*O2Q1;E4s7Os zSp@8DW`v0|KE%^2h`sb^!p4~krb?|5cqiQR2yG>(Jf#XHsCG(ql%R@~>I5#*&n4JH zuIWWw(6bEC;9jt3^j+*$kIr*gJxUX;9w~!WoK`Q&c%=bd2!-V<5#0e`0A#P*Lt)f` z&Ql0fP>t>YK>I*NG3x>q_E)%+&V2PhxV$dC4ivuMRQ8?_c{QvC(K2+N_#=MZ1yr=3 z!*WP3i=3C!WY@S~fhVFq^|H}dGaYgC=(w!-Lqz9K;4BB|{V*tA7fucaWAYtV=T&)h zSVhfwR-W2&K0GFmh6Dc5Etkf6pV_*7d+(N4qC-mfpd89HkcG|TQC;-;f}vo<=Zlq7 zl+`VR#nhhxxW=T`cTe#T#m-bs-4uVrnQB`<#ou&JJ7>I_*pg~lXZF@>Vq+eywacV! z(8Q)xQ!`9=rrd>?9g14$HgtF=tvBW|E7uagK0}Kz*MD)8ztMI}u|rCRPq}*c)qk zhBzl}@lvMl!g=uAv_WPbUc$gB2PJ4_=4xrv&#Xoyla@B`3=LLG8+H~J<$+SlyY8C( zVP_218f3iX14;$p6kKD4eNz{Pz^Q~**goARhsX+hW`*^{I=WO(pQr0-;_2G9RrPf3 zfIs}OkALhb$eMzuh9Uv*+LcOd!{NawRS576lzITVG$Kci_ybB9H=37Mnh|M>jE(E8 zth2)^iW5Dj0-9rVhtCHt73@sz9B z`U!bCh@L4{L4}>}x5Fs45&(!>ly17;anJ71M9(kW29xPC14dw*ZcS7XGFgnpK}P8T zvhoxHs!N<^YTOC-k;6v1-wA`3(Y$~SclFJy(^nJX+EwJ#0Yia>625`3c-(+&xB+Uo zAfPpXxMK*2?uZ=mxKueZD377l#@tjs8AKOMTs8&N)@k|21+nD^;g0UD9q$=j+M^y2*Wf2H}NS%P3Jp zThZz0Y@_DxOo*M|m!Ivc@{_A0;KxL4!dWjOD7~{D0J*fqTxOM5iyQO>6lUHPXYZOK zXTb&yVZuoSd;VfKFi{)lU@bmx5_Dtm&klj2#!fFXGR~PhJ?$l;V9#FLfC3JH(OJc7 zQ);ng_m7W*J6CF;132n&1sZSY_E9;4F$cat+UZun&OaVb#~`t4%N=APaqp@p0f2hT zDrfm*L$?OMvhI{rnUq>IsU<0OYEtLi{)f`WRBhAjwp(vZ9Z0!rXRF_tOm%e6Z~y3} zJ1=P+eKY*8++SAK+;;!cJ-1V<^#0oYxSWx^g+}ruuEopJmo0EEc=%-AYYly`Y!q%V zr58cLolT#2sn7b>7bIlHl4qqLUbsQiLr5&o|>kM zR{DXSv)SFiX+I3MqRUu~#eX&ycf5)l^&0bUu^Js^Y&tf(F4?q0Yud5s-kA`07QWn* z$QB$Wy1D|{Rseh8xYOJjR+Ec-4w=J%q9uLzOt} zxVS9_VFzJx+vFd7u)%PRybCs7)*MSGEMzv5e4K@l5!Ra&;sUWxlvNcc&fWkM{^ z#ChdL@lC5-D~=}u`cNapR6?tcaa`f97y+VjfZGBb9#E^!5z})ZnNCaKyUcW^XWFRL zGIR2zh22$oa2dyFkeRf{`M90X91jj%J8@9{IcU+$4gzUAahmT`>?w9a*DC(B3+Zew zGc|6{Xb&7;*}zw5$H#SU>$U@m8=AT!92$*6%0-WJr5#X8C*s9%GcAJvv>LHn5Kyz; z3oWmMI?23Q${&qclflhiH1BUryECB=pXv0--q+}`(o zG~fQ-QBBTke#Ng}Nt`muq=N5MPsaxKlNgL)lP1-bn zU{QMdUPP0ggL@w7;G(qszVLwk#HmSppq)qFzbN(I3uw}_a8LEUnC$D<`ueB#C8f;b z{R`5rFDt8n)8>w;JyXHy!>PtrXbevuN;R&9#>jMks<8zc^7JdI7EiLJM{DVU?uF?i z>8B;7&6>1%{?a39o8cbPryNKTw>AEk2LO~lv5iyL$oz17fN25DzpPP)A>;XpwqqzC z*Ed5#oePiW_~S~@?$PmVrPo>qWeyt6M#Z2V)ZV*2UpZ&AU1zo4vr~Lh?9{~0xtBF@ z!@PY#+_K7Bcfew+y|wWs7};WCXT)v=u_Kf-XtBdgt<2u*$gCO4ws@@MenD(B*uf2E zU8oSM1P?UON0$~ZM3HA;Q1K|z0cQjatBoAb>|t!7=Eje8n%k2QJwJ$GFpr?@SjR0Q za?~q=MD}1c&8&@B-5=vXQ$npBR*7RlZ2GxlJl;sP!?!8)LNRL zQOa7Z%y0z86qQ2u(?JTfi?5+(@5dg%ESl6}$fbARsU=n!DsJ~_M zEfe9#!KM)E*MbnFLM5dARv!#5C4{0uOI9`!HPUBb68Tg10x%h-#X;OkxlDtf0v@w6 z*9;E^&G0Mas_(HZr032T62(smFAQ|hZrorzD z+vDXR^bNz&OkV#$}Im|={;%D-IWl#3Wfe% z6c3hP4=Y-V$99ek(OF{oHRCL?hh}Q2yruzE?kp796WRR)ELdRo=pVD5ZT5or?2Oez zew`2-3Ll@Yl{Nt*r7X@k0gKrk;fT%pvQw(cYE)CdbvER_wED_YSTsR0Dez|bmk~&t z^dfaolTxG>`ab(X8CG#utA~P3+Ksbvh25;PKBJt8!i7pE`d8doB9#YijBF&foO zVFFTX#VTX6A)Ou9onuycGq;$jtcPi_bkdnFf?fo)ssI3cmMU)^nm#l$tVyj&sY{c( z=G6JUi?m8RTf7ml0`RMB1s}K0kou4_s*s!?!SmO8_ z$>V1ikDpDPBgu2Yg>%6~&4npv%H4pav&C;aN`Dv+Rfm#752es!6StxjF{3XvKW$`u zsfieeaanGue7Za-w!rs>*<+8a^FQ11Jjosd7f+cg=5cb_fsJM&P&rw9ZE|`tVb%81 zAE00eS|57In?fiib|#Wl@KDtn^#H7b{Wl ztW`LnwW&T@n_7hOPP`GHsk{hZ+Gg6|6WJAS|` z=)$-X3`LaP@QMoheg)%9Mr_8j(-2to%qG=tsse<*PWN;KqRb; z${`hB3)40;ZxaIN<-o<5i$?CW9f1MrO#s)J|A^%YciUXehi$)WTWs&Wx9`tK{&?i$ zqYsXMe&(|?fAb|yoJyV;(oPI5o*)U2thwcf;&7@A^03=iZ(Uui?_MbDo8_ z^1@$UT6n7ei)iBXx#a1fb~?Ct`r^XTi;3~*V}^N~eHlLsyv_FGCjh*`XMwlb!`u?X zT!LGwx<2Kup}u{<+m0XYLU6|We7ei$8w-<(QEW>--=zuvs7ZnECL|p2`IJ_85oIF+ zn&NK5)-D8Cicv5lH3WMATdyEEjNmAOlL#=zRL&wehaiA}YT-P#s47OW6-J;UxQqbR zLmi&-Q*2#F@N)onjM5rCk5EF*tk?hshqHD$<7L!miStscd3UJd@PQplPT!LZU=&91WgF&s$JMxkD$>6JWO+$ zb6b~rUZ|zwr_2t33!$9PAp2M-q;In#K5r=FMdcRYaP!mH9KJNM>^JramW2c!A)WGn D5#2rBkw@t$ik50xvXxv^OEJ|*v=pfl9LJ4OBT8CBNFlcc)H=kOd!i_l zM|tlQMKo3PBPeJ;wo?3#+4hz zA73%&vzDnFmY%h2hcBm{Y{AlP)6wS(9MuL-FJv7v?JRS1M4vV-lN*kyXFR6B+jJPX zHou&6vP(Hr&ly%`*~pl7+7A-Cfx!sC|G{^FY?6{xA}Qd!Q3`-m4+_YS>*RJ9H+YxGL__GV-PyGT(QuW^Kon*bP?&pDZDTxS2sFA-l3|=H@wOma9m@ zKy0*#jyxMlE)?=+u8=lz$y@ocsq^FGW68HxZ}0-R{+tof8(CU))l@2LWt~*2*x~7X zS(qIFvp*%ZQ+iomkJREXz(cE@=!QqAcBcEGfyK&|gq*2kSjDAY_&#l$m09z}A!c0Mpx^ z(Y7MHZJT*S!G+QDYx?c?0JH_3Gp!4+g0xcL4EZtO4W4xtyhT26E=;T?Zv%Er%Z38* z=AN6%8);rZajk8KBtil>u4-qCra)H!Dn}s7?Z}wUw+p%Dyk*ZI9NR&D+XrC~$|P?% z357!_iA!x)^E9&#&srId0d#5B#*`r#b>4xRP$~uX0bvmzVM6SLIs0co0ASjwduM+= z{LA6(?niw)eY-uA6>YLiYif9X_QUSY_(r@Md$|&Oc`ugOiwtd#S0c%ZnuG=MpOm#) zSA27FW3t*cSm_$vavrSRU)$@ND66$t&px5yq4MRL7TJxR{qRgRcD90liLF~eDq7;s z?E&LkLE+iHiRc7^wJ`_+4yNHY}Uq?s-HIz}nAO+-H0OUaD zXjK=BSU*QbYr7?AraiFIZ`XiD$=9*KN6=nN@<)^@AIk!N()vZfp9J^|&bWkQ@f8D? zM$bQ^IzItILVk_}%>1mGM~rxoL3p6@2Y^7sY9OHw70(E4SCQ4oLs$!F?iy zr^?^0#ZPapY^+q{!WqOfdiqxIT}HLZD* z7xHlA#l0#zHt`a?b#NL8L@nBNcjeAXHQHZ^_HT_pc>VtCd(qKdb<_iSbHl}26|TMu z41gSA2`9a1lAt*{{&TpOBp;BJtPja#^|13XIHCbb{)v6nv_uFXHlnwLS1>99c<7Ri zTWmBG&0wrCUp(Q(qgi(rUr7LgP{ew%3rt}b=)609XS%8lRJ4ID_8@;h|JnB*Ym-l* z1xy_e41Q4r28#5nRX_DB9j-@przNj9292d9(_#t9b5h1Ku`wHsRta8Uefh1jE#fmgh zXIZ#h?H5Vphr z{tRlJKuE0gQ1(9Q_o(_Q5QR2_+k|Eg{XUx(sS{UDzfwcc`|)PsD&kghxKjP|0=)zi z#qMLigLVwQY!3iwYFvYrX#FhzjQu|M+uR?gzxe)Mbaq#rJzlA}b5W@?!2AzlM14T} zv8eZJ?8O+1cMJ~xIwrRd0U7&5b1`%LW!2QJ55GErtNVa7Ieo4YJ?GtkJ`e3h-`G{( z5YEmdI`Eo~K~AOIwp1!#V9Pn=wN&cXvXQILz&(o<(y0`Wf?0kB$sm#;Bm!fvBKJ)s z0;3m^!(H+&BzOT5H#UyNF9BvHhT=Ozo>w z`8skF$bpV3*XRMz%ha=rme7m5k+twDh);bUPBa}LF#|tqI{hChBk%CS`>R)Oc)R!( zzNaj~{n9zI%V+9EFA$gbo3IEEO?w0gT<4 literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/IsaDescriptionLexer.cpython-312.pyc b/HybroGen/__pycache__/IsaDescriptionLexer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9094416abace4d880d162dc68b16468b90e4eb72 GIT binary patch literal 4975 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 literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/IsaDescriptionListener.cpython-312.pyc b/HybroGen/__pycache__/IsaDescriptionListener.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b3af0997275765a67b91abf9fa9a8bbb075451a1 GIT binary patch literal 7640 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 literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/ProxyDb.cpython-312.pyc b/HybroGen/__pycache__/ProxyDb.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2df604b604f4100964021bfaa25974867a3a4cb9 GIT binary patch literal 15935 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 UEAx(4d^6*yTy%2MI<_wV4^^>3R{#J2 literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/Register.cpython-312.pyc b/HybroGen/__pycache__/Register.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74ab688aefa4eac9e6bb2bf144a6f0f8fcfb40fd GIT binary patch literal 3665 zcmb_eO>7%Q6rNrGjbm@@{Is%DC*7n#>rf@Mil7t<0zm?oP|^t6PfhC~(0+YXFR(Bnf8#*5per;|AUq^0nIVkaAxwFqHZ=>RqGkhmxgLAP9W+)z zct}jLpfIwaGG!sa)H`G$$O3>N76c5l5MYFb0V#_BMi~X{VNt*s>j8|j7@)@DfW1ru zOt4jNC9^k)YgI%h5wEZgMOd!Lxs3MEs|m2~dT>6Xn`^Y$t?_49g< z4sBe|@%;5tZrOB)<}KSSS%q@R9m}nrC35Q90<*9Cmf4jR`A^qYOL-gq2u|tI^RCB) zcTf(%uVD)xtt;!q5DEl_Bk4u5L}1j~D|EP1G%=EQ)La>A=~UPU_t|VL0HcT;RY*2C z`}7}Z4w=qUhe{VX(U$d2Tv|B`zHu};5;nJ$^I)z+rKL`Ig@ey;IkaGXW#;WN&#F$) zGK<$Z9&Vu>y8iOapVa~m@iIs{&4Wm#h z*oIN7ynk7Ga78mETDs-r3BV!Nr~ zyTSWf1O9+?zomZAJS3gBR3VR**~bc}pv$T}0iBRt8+j5YoVaD$pUQZu9%(W6P9KGZ zRull(r^kRvFURvbnBa|zcsUOOFd;Xf_qQ9ZxM*wEl_zc_DWpR9AZUOrp5}yeD=TJ+ zx!j!~#&-w#1hABhF$StBIhyck((r#4+5slec%7!VXu3}IEvo-GxI^FAZ%-@!yL(pf z1m9v|lKes<@Hz-4Jv6??RIH}EF%+r{QpEoQio@XL9XfPiS}_l;2sf87 z-E*ip?xB@Afwa>5Y5mW)kLkj(pi9@rz=mnJR(04B0|!e*b*oO>OYyV-O!1KAWiFpJ(c3n%c6 zneSkMuKC=pahxPoi+>zVvR*;rGuI$ZMNxHCf0H z>JvWRjRtx|W^$)TxtgGF8iuZ>^{i{J za5eZE@ikY2-#%YsDt@?KJ>IRaN&O@363GT;Un=@jT#=24$DDZWh)*=f4q8vAjo2$8^s{vD3Id2%e4^75*56Ak=M-cFf z$nh)0@dLn5BTOP-UEv~+-$v;i!g~lJkUj$GaWj-eS?3r(0#L9n1Kc6c)kr9`m!zSQ zy+I{(VlS+OP9g~DHI&8?h7mFdBM74iV=YN&kKu5*5mZ91?c%6es1M@YX*?XmT5x$u f-*0;213m+Dm}nN7{w$y<%8T#?#RQikiY@;F;;H9V literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/RegisterDescriptionLexer.cpython-312.pyc b/HybroGen/__pycache__/RegisterDescriptionLexer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1364491876c2e13ca80d93616aa2c80b5e1b891d GIT binary patch literal 5102 zcmcgwTTC3+8J;0JYDH<)hvuPAeXH^kYDY%XG;*3tOZ$@AjgtDQ|3AxO6FHiw zm3of&&i|kD?LX)I|GDyxrpXkfN#TR+4}ui+5h|s`tqXUSL3ouiD1**XZxR|MlA~vc zUX+;}qcbLRS}gtWUTLs(pcvelC`DNU{Ep9YGrZ2z)GY65LQyk>^OP1q>}7>hoca-2 zVKA$VDyUX^&ydr2~P%4)zm5^Ga z)dd(LIE^e(l-5>;bnoZL@bJ;26B8`ypUf-^q^qmjY1-dEnNDYx$r%_Yfy8+zcqlPW z9o8wH2JV0q^spRUgH4s57V@yh!#Y5xo-p7zFxH4DG$Tqah>Fv&4NGk&V(?MK@&Uxk zA+T9bNGO3?%@M@9lZXvlgibWNg+;BgNmwMLiAT9PESw=EEIQs7T3UtY2x*nEW$Shc zaNAatw?n9!pltKL+}4hD?K=>6L`0sD2)MQxw4EKoc0wN7rGWhKL)gBn3$dfK*t3p@ zQS01|*wul!yPFFs#Hs1tgW8@RQ6QuT+)l_Nk4ZRt$fJ*-_E;}suQ%G>y(sT3b08*! z>>Cs&3E6)@7$@YwpwLgq;|GNyLJkfJ$6(Cco_JC?PRNs<)^|vV6LQFt`=i1HA<-hM zB{nGNgbeIMiv#;TeB8q)JnSouZ=m1PVu*tkh(mFSB_w{B3p!0AIb4Nx!y`hFki;;` zi4nw+Bn$-{lpGaQLPo2x?#Q^%M##}Ii6i9LQK)gkWNZRk#*cY;9P#)G#EEgl6Hen( zTu>xW)uMLt6#i15l)(Q_>saG7O{TCs^|Xi2AU;!%m^y{%XfkQ*=p9ImpJGG^8e_o? zhjO{IRyJ?C;gnn399nwT znj17{?+M4u>8zbMt*B{dtn7R~J2#s!7fq{Ue#zBr)5@lES;sW`#*>x?b`|)u{{mkq zQ146Sm+C*GwsK7`+pD5-S-L2_TQPh?Ol&Ce8{**&zZj$;lwV*xZzJ5bRfzSactyOO`9nJw z?-DlMw!NnW5bi`_GJKDHl`<)vHYiw&l*yFNveObUzLKDwE47!-M4g9P!Q@YueT58a zi4&zRQu@cr+SIx@xI;WHcI!aCfBx@#I8bA|5^HFzvhA0bW4JB22YM zB&!jPk`rUD&_6md5=)M|OdLQQIG*fJ_Kn0`?pSQ_MA8+Ku@i}SGUoC}j>QJzPq{3% zMpTy_Po=s%-0fkvhkL9hFl;p=gb`X0S`oG)Y(v-%;8Z`rO&!xcNtd5n$j>k2Gxxvn z&^M^x`8~iZG`tI;ET)UhGWC7%>@vMfN^{10|2^P#cK-`8k2bxujIYH9JcXgQv_48y zDD$|1dTC?+V;~_dQ>hJ`25K8NJ#AwZEm0AYbhw_5y&c^V+2!nodDC*mR4O~0&8JeX znt9I5oS85!8@6$`+}p@u=N`+>EacMpIm>0z`B^t$n3*gx?D4tiK%ZNE#4?R+2DkqH zx!F9ttozeo$Q8gWoDB2ufwb3ZyGm-_#zGEdHI;gPA)Q-q34+VuI4qrgma7=|X&6MS3&54k*@YR? z0$;enl1s zW-rY=JD1C5)_E3;swf7ht@O-H+8W3fYh1=&vR&TJ8?aO?oO51aTx~sU88eqlr6Qb5 zI=Wms>k`AZ`jFKNVB@;zg7joDr0_o^%0lSI#&-a|JWqWn*IkzzZp!T|a{C+FwcvHR zx6uD#XYbpU#UNep9Jv`9T?vi;)O;;{wc*kuHzXh4^PYRnu7*z17(At3AKn_v?NCq&O~owe1TmJo(?BKS5O=p}oPr zU45ut_J$ZyTs}RU&sjY#$vuK292! z^QO9I?hVS?3ss&U?}`VC6Y-#hvmcIA%Erde7@DR(rmFr-)%=N)R~h~$Q@O%azTCIM jR9`9oBUAqY+xQ6^zRho=oBoxgchKQ03!hU^c&7gYNCm5C literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/RegisterDescriptionListener.cpython-312.pyc b/HybroGen/__pycache__/RegisterDescriptionListener.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..293a801a5bf5a3c6c7683581292734a4ad06a13b GIT binary patch literal 6685 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 Y<0?bxqaMSyOhdu7bw8)@mw=i74}rGB2LJ#7 literal 0 HcmV?d00001 diff --git a/HybroGen/__pycache__/__init__.cpython-312.pyc b/HybroGen/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..207e223619ebe21ba65ef94088f485ccdb103779 GIT binary patch literal 146 zcmX@j%ge<81Y74`&jitrK?FMZ%mNgd&QQsq$>_I|p@<2{`wUX^%TPZfKQ}ceKRGc+ zzcAOx!obADNZ+F}sVLt)H4njvkI&4@EQycTE2#X%VUwGmQks)$SHuc5ff0y{L5z>g LjEsy$%s>_Z2IwKN literal 0 HcmV?d00001 diff --git a/HybroLang/.antlr/HybroLang.interp b/HybroLang/.antlr/HybroLang.interp new file mode 100644 index 0000000..8ea5afa --- /dev/null +++ b/HybroLang/.antlr/HybroLang.interp @@ -0,0 +1,125 @@ +token literal names: +null +'(' +')' +'{' +'}' +',' +';' +'for' +'if' +'else' +'return' +'=' +'[' +']' +'*' +'/' +'+' +'-' +'<<' +'>>' +'&' +'|' +'^' +'int' +'uint' +'sint' +'suint' +'flt' +'cpl' +'pix' +'ipv4' +'ipv6' +'[]' +'==' +'!=' +'<' +'>' +'<=' +'>=' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +DecimalFloatingConstant +IntegerConstant +DecimalConstant +Name +INLINE +WhiteSpace +LineComment +NewLine + +rule names: +compilationunit +function +fndcl +fnprototype +fnbody +paramdcllist +localvardef +vardcllist +vardcl +actionlist +condexpr +action +returnexpr +affectexpr +unaryexpr +varorvalue +datatype +intconstvalue +constvalue +constinline +typebase +condOperator + + +atn: +[4, 1, 46, 204, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 1, 0, 4, 0, 46, 8, 0, 11, 0, 12, 0, 47, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 5, 4, 63, 8, 4, 10, 4, 12, 4, 66, 9, 4, 1, 4, 1, 4, 3, 4, 70, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 5, 5, 77, 8, 5, 10, 5, 12, 5, 80, 9, 5, 1, 5, 3, 5, 83, 8, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 5, 7, 91, 8, 7, 10, 7, 12, 7, 94, 9, 7, 1, 8, 1, 8, 1, 8, 1, 9, 5, 9, 100, 8, 9, 10, 9, 12, 9, 103, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 136, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 152, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 169, 8, 14, 10, 14, 12, 14, 172, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 181, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 3, 17, 189, 8, 17, 1, 18, 1, 18, 1, 18, 3, 18, 194, 8, 18, 1, 19, 1, 19, 1, 20, 1, 20, 3, 20, 200, 8, 20, 1, 21, 1, 21, 1, 21, 0, 1, 28, 22, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 0, 6, 1, 0, 14, 15, 1, 0, 16, 17, 1, 0, 18, 19, 1, 0, 20, 22, 1, 0, 23, 31, 1, 0, 33, 38, 201, 0, 45, 1, 0, 0, 0, 2, 49, 1, 0, 0, 0, 4, 52, 1, 0, 0, 0, 6, 56, 1, 0, 0, 0, 8, 60, 1, 0, 0, 0, 10, 82, 1, 0, 0, 0, 12, 84, 1, 0, 0, 0, 14, 87, 1, 0, 0, 0, 16, 95, 1, 0, 0, 0, 18, 101, 1, 0, 0, 0, 20, 104, 1, 0, 0, 0, 22, 135, 1, 0, 0, 0, 24, 137, 1, 0, 0, 0, 26, 151, 1, 0, 0, 0, 28, 153, 1, 0, 0, 0, 30, 180, 1, 0, 0, 0, 32, 182, 1, 0, 0, 0, 34, 188, 1, 0, 0, 0, 36, 193, 1, 0, 0, 0, 38, 195, 1, 0, 0, 0, 40, 197, 1, 0, 0, 0, 42, 201, 1, 0, 0, 0, 44, 46, 3, 2, 1, 0, 45, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 45, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 1, 1, 0, 0, 0, 49, 50, 3, 4, 2, 0, 50, 51, 3, 8, 4, 0, 51, 3, 1, 0, 0, 0, 52, 53, 3, 32, 16, 0, 53, 54, 5, 42, 0, 0, 54, 55, 3, 6, 3, 0, 55, 5, 1, 0, 0, 0, 56, 57, 5, 1, 0, 0, 57, 58, 3, 10, 5, 0, 58, 59, 5, 2, 0, 0, 59, 7, 1, 0, 0, 0, 60, 64, 5, 3, 0, 0, 61, 63, 3, 12, 6, 0, 62, 61, 1, 0, 0, 0, 63, 66, 1, 0, 0, 0, 64, 62, 1, 0, 0, 0, 64, 65, 1, 0, 0, 0, 65, 67, 1, 0, 0, 0, 66, 64, 1, 0, 0, 0, 67, 69, 3, 18, 9, 0, 68, 70, 3, 24, 12, 0, 69, 68, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 72, 5, 4, 0, 0, 72, 9, 1, 0, 0, 0, 73, 78, 3, 16, 8, 0, 74, 75, 5, 5, 0, 0, 75, 77, 3, 16, 8, 0, 76, 74, 1, 0, 0, 0, 77, 80, 1, 0, 0, 0, 78, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 83, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 81, 83, 1, 0, 0, 0, 82, 73, 1, 0, 0, 0, 82, 81, 1, 0, 0, 0, 83, 11, 1, 0, 0, 0, 84, 85, 3, 14, 7, 0, 85, 86, 5, 6, 0, 0, 86, 13, 1, 0, 0, 0, 87, 92, 3, 16, 8, 0, 88, 89, 5, 5, 0, 0, 89, 91, 5, 42, 0, 0, 90, 88, 1, 0, 0, 0, 91, 94, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 15, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 95, 96, 3, 32, 16, 0, 96, 97, 5, 42, 0, 0, 97, 17, 1, 0, 0, 0, 98, 100, 3, 22, 11, 0, 99, 98, 1, 0, 0, 0, 100, 103, 1, 0, 0, 0, 101, 99, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 19, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 104, 105, 3, 30, 15, 0, 105, 106, 3, 42, 21, 0, 106, 107, 3, 30, 15, 0, 107, 21, 1, 0, 0, 0, 108, 109, 3, 26, 13, 0, 109, 110, 5, 6, 0, 0, 110, 136, 1, 0, 0, 0, 111, 112, 5, 7, 0, 0, 112, 113, 5, 1, 0, 0, 113, 114, 3, 26, 13, 0, 114, 115, 5, 6, 0, 0, 115, 116, 3, 20, 10, 0, 116, 117, 5, 6, 0, 0, 117, 118, 3, 26, 13, 0, 118, 119, 5, 2, 0, 0, 119, 120, 5, 3, 0, 0, 120, 121, 3, 18, 9, 0, 121, 122, 5, 4, 0, 0, 122, 136, 1, 0, 0, 0, 123, 124, 5, 8, 0, 0, 124, 125, 5, 1, 0, 0, 125, 126, 3, 20, 10, 0, 126, 127, 5, 2, 0, 0, 127, 128, 5, 3, 0, 0, 128, 129, 3, 18, 9, 0, 129, 130, 5, 4, 0, 0, 130, 131, 5, 9, 0, 0, 131, 132, 5, 3, 0, 0, 132, 133, 3, 18, 9, 0, 133, 134, 5, 4, 0, 0, 134, 136, 1, 0, 0, 0, 135, 108, 1, 0, 0, 0, 135, 111, 1, 0, 0, 0, 135, 123, 1, 0, 0, 0, 136, 23, 1, 0, 0, 0, 137, 138, 5, 10, 0, 0, 138, 139, 3, 28, 14, 0, 139, 140, 5, 6, 0, 0, 140, 25, 1, 0, 0, 0, 141, 142, 5, 42, 0, 0, 142, 143, 5, 11, 0, 0, 143, 152, 3, 28, 14, 0, 144, 145, 5, 42, 0, 0, 145, 146, 5, 12, 0, 0, 146, 147, 3, 28, 14, 0, 147, 148, 5, 13, 0, 0, 148, 149, 5, 11, 0, 0, 149, 150, 3, 28, 14, 0, 150, 152, 1, 0, 0, 0, 151, 141, 1, 0, 0, 0, 151, 144, 1, 0, 0, 0, 152, 27, 1, 0, 0, 0, 153, 154, 6, 14, -1, 0, 154, 155, 3, 30, 15, 0, 155, 170, 1, 0, 0, 0, 156, 157, 10, 5, 0, 0, 157, 158, 7, 0, 0, 0, 158, 169, 3, 28, 14, 6, 159, 160, 10, 4, 0, 0, 160, 161, 7, 1, 0, 0, 161, 169, 3, 28, 14, 5, 162, 163, 10, 3, 0, 0, 163, 164, 7, 2, 0, 0, 164, 169, 3, 28, 14, 4, 165, 166, 10, 2, 0, 0, 166, 167, 7, 3, 0, 0, 167, 169, 3, 28, 14, 3, 168, 156, 1, 0, 0, 0, 168, 159, 1, 0, 0, 0, 168, 162, 1, 0, 0, 0, 168, 165, 1, 0, 0, 0, 169, 172, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 170, 171, 1, 0, 0, 0, 171, 29, 1, 0, 0, 0, 172, 170, 1, 0, 0, 0, 173, 174, 5, 42, 0, 0, 174, 175, 5, 12, 0, 0, 175, 176, 3, 28, 14, 0, 176, 177, 5, 13, 0, 0, 177, 181, 1, 0, 0, 0, 178, 181, 3, 36, 18, 0, 179, 181, 5, 42, 0, 0, 180, 173, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 180, 179, 1, 0, 0, 0, 181, 31, 1, 0, 0, 0, 182, 183, 3, 40, 20, 0, 183, 184, 3, 34, 17, 0, 184, 185, 3, 34, 17, 0, 185, 33, 1, 0, 0, 0, 186, 189, 5, 40, 0, 0, 187, 189, 3, 38, 19, 0, 188, 186, 1, 0, 0, 0, 188, 187, 1, 0, 0, 0, 189, 35, 1, 0, 0, 0, 190, 194, 5, 40, 0, 0, 191, 194, 5, 39, 0, 0, 192, 194, 3, 38, 19, 0, 193, 190, 1, 0, 0, 0, 193, 191, 1, 0, 0, 0, 193, 192, 1, 0, 0, 0, 194, 37, 1, 0, 0, 0, 195, 196, 5, 43, 0, 0, 196, 39, 1, 0, 0, 0, 197, 199, 7, 4, 0, 0, 198, 200, 5, 32, 0, 0, 199, 198, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 41, 1, 0, 0, 0, 201, 202, 7, 5, 0, 0, 202, 43, 1, 0, 0, 0, 15, 47, 64, 69, 78, 82, 92, 101, 135, 151, 168, 170, 180, 188, 193, 199] \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLang.tokens b/HybroLang/.antlr/HybroLang.tokens new file mode 100644 index 0000000..574a34a --- /dev/null +++ b/HybroLang/.antlr/HybroLang.tokens @@ -0,0 +1,84 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +DecimalFloatingConstant=39 +IntegerConstant=40 +DecimalConstant=41 +Name=42 +INLINE=43 +WhiteSpace=44 +LineComment=45 +NewLine=46 +'('=1 +')'=2 +'{'=3 +'}'=4 +','=5 +';'=6 +'for'=7 +'if'=8 +'else'=9 +'return'=10 +'='=11 +'['=12 +']'=13 +'*'=14 +'/'=15 +'+'=16 +'-'=17 +'<<'=18 +'>>'=19 +'&'=20 +'|'=21 +'^'=22 +'int'=23 +'uint'=24 +'sint'=25 +'suint'=26 +'flt'=27 +'cpl'=28 +'pix'=29 +'ipv4'=30 +'ipv6'=31 +'[]'=32 +'=='=33 +'!='=34 +'<'=35 +'>'=36 +'<='=37 +'>='=38 diff --git a/HybroLang/.antlr/HybroLangBaseListener.java b/HybroLang/.antlr/HybroLangBaseListener.java new file mode 100644 index 0000000..1196c27 --- /dev/null +++ b/HybroLang/.antlr/HybroLangBaseListener.java @@ -0,0 +1,327 @@ +// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link HybroLangListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class HybroLangBaseListener implements HybroLangListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCompilationunit(HybroLangParser.CompilationunitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCompilationunit(HybroLangParser.CompilationunitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFunction(HybroLangParser.FunctionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFunction(HybroLangParser.FunctionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFndcl(HybroLangParser.FndclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFndcl(HybroLangParser.FndclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFnprototype(HybroLangParser.FnprototypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFnprototype(HybroLangParser.FnprototypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFnbody(HybroLangParser.FnbodyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFnbody(HybroLangParser.FnbodyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterParamdcllist(HybroLangParser.ParamdcllistContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitParamdcllist(HybroLangParser.ParamdcllistContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLocalvardef(HybroLangParser.LocalvardefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLocalvardef(HybroLangParser.LocalvardefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVardcllist(HybroLangParser.VardcllistContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVardcllist(HybroLangParser.VardcllistContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVardcl(HybroLangParser.VardclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVardcl(HybroLangParser.VardclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterActionlist(HybroLangParser.ActionlistContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitActionlist(HybroLangParser.ActionlistContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCondexpr(HybroLangParser.CondexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCondexpr(HybroLangParser.CondexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAction(HybroLangParser.ActionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAction(HybroLangParser.ActionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterReturnexpr(HybroLangParser.ReturnexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitReturnexpr(HybroLangParser.ReturnexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAffectexpr(HybroLangParser.AffectexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAffectexpr(HybroLangParser.AffectexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterUnaryexpr(HybroLangParser.UnaryexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitUnaryexpr(HybroLangParser.UnaryexprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDatatype(HybroLangParser.DatatypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDatatype(HybroLangParser.DatatypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIntconstvalue(HybroLangParser.IntconstvalueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIntconstvalue(HybroLangParser.IntconstvalueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterConstvalue(HybroLangParser.ConstvalueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitConstvalue(HybroLangParser.ConstvalueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterConstinline(HybroLangParser.ConstinlineContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitConstinline(HybroLangParser.ConstinlineContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypebase(HybroLangParser.TypebaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypebase(HybroLangParser.TypebaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCondOperator(HybroLangParser.CondOperatorContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCondOperator(HybroLangParser.CondOperatorContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangLexer.interp b/HybroLang/.antlr/HybroLangLexer.interp new file mode 100644 index 0000000..9840595 --- /dev/null +++ b/HybroLang/.antlr/HybroLangLexer.interp @@ -0,0 +1,162 @@ +token literal names: +null +'(' +')' +'{' +'}' +',' +';' +'for' +'if' +'else' +'return' +'=' +'[' +']' +'*' +'/' +'+' +'-' +'<<' +'>>' +'&' +'|' +'^' +'int' +'uint' +'sint' +'suint' +'flt' +'cpl' +'pix' +'ipv4' +'ipv6' +'[]' +'==' +'!=' +'<' +'>' +'<=' +'>=' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +DecimalFloatingConstant +IntegerConstant +DecimalConstant +Name +INLINE +WhiteSpace +LineComment +NewLine + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +T__7 +T__8 +T__9 +T__10 +T__11 +T__12 +T__13 +T__14 +T__15 +T__16 +T__17 +T__18 +T__19 +T__20 +T__21 +T__22 +T__23 +T__24 +T__25 +T__26 +T__27 +T__28 +T__29 +T__30 +T__31 +T__32 +T__33 +T__34 +T__35 +T__36 +T__37 +DecimalFloatingConstant +ExponentPart +FloatingSuffix +FractionalConstant +IntegerConstant +DecimalConstant +DigitSequence +Digit +NonzeroDigit +Sign +Name +INLINE +WhiteSpace +LineComment +NewLine + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[4, 0, 46, 320, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 3, 38, 228, 8, 38, 1, 38, 3, 38, 231, 8, 38, 1, 39, 1, 39, 3, 39, 235, 8, 39, 1, 39, 1, 39, 1, 39, 3, 39, 240, 8, 39, 1, 39, 3, 39, 243, 8, 39, 1, 40, 1, 40, 1, 41, 3, 41, 248, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 255, 8, 41, 1, 42, 1, 42, 1, 43, 1, 43, 5, 43, 261, 8, 43, 10, 43, 12, 43, 264, 9, 43, 1, 44, 4, 44, 267, 8, 44, 11, 44, 12, 44, 268, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 5, 48, 279, 8, 48, 10, 48, 12, 48, 282, 9, 48, 1, 49, 1, 49, 1, 49, 1, 49, 4, 49, 288, 8, 49, 11, 49, 12, 49, 289, 1, 49, 1, 49, 1, 50, 4, 50, 295, 8, 50, 11, 50, 12, 50, 296, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 5, 51, 305, 8, 51, 10, 51, 12, 51, 308, 9, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 3, 52, 315, 8, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 306, 0, 53, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 0, 81, 0, 83, 0, 85, 40, 87, 41, 89, 0, 91, 0, 93, 0, 95, 0, 97, 42, 99, 43, 101, 44, 103, 45, 105, 46, 1, 0, 8, 4, 0, 70, 70, 76, 76, 102, 102, 108, 108, 1, 0, 48, 57, 1, 0, 49, 57, 2, 0, 43, 43, 45, 45, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 1, 0, 41, 41, 2, 0, 9, 9, 32, 32, 326, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 1, 107, 1, 0, 0, 0, 3, 109, 1, 0, 0, 0, 5, 111, 1, 0, 0, 0, 7, 113, 1, 0, 0, 0, 9, 115, 1, 0, 0, 0, 11, 117, 1, 0, 0, 0, 13, 119, 1, 0, 0, 0, 15, 123, 1, 0, 0, 0, 17, 126, 1, 0, 0, 0, 19, 131, 1, 0, 0, 0, 21, 138, 1, 0, 0, 0, 23, 140, 1, 0, 0, 0, 25, 142, 1, 0, 0, 0, 27, 144, 1, 0, 0, 0, 29, 146, 1, 0, 0, 0, 31, 148, 1, 0, 0, 0, 33, 150, 1, 0, 0, 0, 35, 152, 1, 0, 0, 0, 37, 155, 1, 0, 0, 0, 39, 158, 1, 0, 0, 0, 41, 160, 1, 0, 0, 0, 43, 162, 1, 0, 0, 0, 45, 164, 1, 0, 0, 0, 47, 168, 1, 0, 0, 0, 49, 173, 1, 0, 0, 0, 51, 178, 1, 0, 0, 0, 53, 184, 1, 0, 0, 0, 55, 188, 1, 0, 0, 0, 57, 192, 1, 0, 0, 0, 59, 196, 1, 0, 0, 0, 61, 201, 1, 0, 0, 0, 63, 206, 1, 0, 0, 0, 65, 209, 1, 0, 0, 0, 67, 212, 1, 0, 0, 0, 69, 215, 1, 0, 0, 0, 71, 217, 1, 0, 0, 0, 73, 219, 1, 0, 0, 0, 75, 222, 1, 0, 0, 0, 77, 225, 1, 0, 0, 0, 79, 242, 1, 0, 0, 0, 81, 244, 1, 0, 0, 0, 83, 254, 1, 0, 0, 0, 85, 256, 1, 0, 0, 0, 87, 258, 1, 0, 0, 0, 89, 266, 1, 0, 0, 0, 91, 270, 1, 0, 0, 0, 93, 272, 1, 0, 0, 0, 95, 274, 1, 0, 0, 0, 97, 276, 1, 0, 0, 0, 99, 283, 1, 0, 0, 0, 101, 294, 1, 0, 0, 0, 103, 300, 1, 0, 0, 0, 105, 314, 1, 0, 0, 0, 107, 108, 5, 40, 0, 0, 108, 2, 1, 0, 0, 0, 109, 110, 5, 41, 0, 0, 110, 4, 1, 0, 0, 0, 111, 112, 5, 123, 0, 0, 112, 6, 1, 0, 0, 0, 113, 114, 5, 125, 0, 0, 114, 8, 1, 0, 0, 0, 115, 116, 5, 44, 0, 0, 116, 10, 1, 0, 0, 0, 117, 118, 5, 59, 0, 0, 118, 12, 1, 0, 0, 0, 119, 120, 5, 102, 0, 0, 120, 121, 5, 111, 0, 0, 121, 122, 5, 114, 0, 0, 122, 14, 1, 0, 0, 0, 123, 124, 5, 105, 0, 0, 124, 125, 5, 102, 0, 0, 125, 16, 1, 0, 0, 0, 126, 127, 5, 101, 0, 0, 127, 128, 5, 108, 0, 0, 128, 129, 5, 115, 0, 0, 129, 130, 5, 101, 0, 0, 130, 18, 1, 0, 0, 0, 131, 132, 5, 114, 0, 0, 132, 133, 5, 101, 0, 0, 133, 134, 5, 116, 0, 0, 134, 135, 5, 117, 0, 0, 135, 136, 5, 114, 0, 0, 136, 137, 5, 110, 0, 0, 137, 20, 1, 0, 0, 0, 138, 139, 5, 61, 0, 0, 139, 22, 1, 0, 0, 0, 140, 141, 5, 91, 0, 0, 141, 24, 1, 0, 0, 0, 142, 143, 5, 93, 0, 0, 143, 26, 1, 0, 0, 0, 144, 145, 5, 42, 0, 0, 145, 28, 1, 0, 0, 0, 146, 147, 5, 47, 0, 0, 147, 30, 1, 0, 0, 0, 148, 149, 5, 43, 0, 0, 149, 32, 1, 0, 0, 0, 150, 151, 5, 45, 0, 0, 151, 34, 1, 0, 0, 0, 152, 153, 5, 60, 0, 0, 153, 154, 5, 60, 0, 0, 154, 36, 1, 0, 0, 0, 155, 156, 5, 62, 0, 0, 156, 157, 5, 62, 0, 0, 157, 38, 1, 0, 0, 0, 158, 159, 5, 38, 0, 0, 159, 40, 1, 0, 0, 0, 160, 161, 5, 124, 0, 0, 161, 42, 1, 0, 0, 0, 162, 163, 5, 94, 0, 0, 163, 44, 1, 0, 0, 0, 164, 165, 5, 105, 0, 0, 165, 166, 5, 110, 0, 0, 166, 167, 5, 116, 0, 0, 167, 46, 1, 0, 0, 0, 168, 169, 5, 117, 0, 0, 169, 170, 5, 105, 0, 0, 170, 171, 5, 110, 0, 0, 171, 172, 5, 116, 0, 0, 172, 48, 1, 0, 0, 0, 173, 174, 5, 115, 0, 0, 174, 175, 5, 105, 0, 0, 175, 176, 5, 110, 0, 0, 176, 177, 5, 116, 0, 0, 177, 50, 1, 0, 0, 0, 178, 179, 5, 115, 0, 0, 179, 180, 5, 117, 0, 0, 180, 181, 5, 105, 0, 0, 181, 182, 5, 110, 0, 0, 182, 183, 5, 116, 0, 0, 183, 52, 1, 0, 0, 0, 184, 185, 5, 102, 0, 0, 185, 186, 5, 108, 0, 0, 186, 187, 5, 116, 0, 0, 187, 54, 1, 0, 0, 0, 188, 189, 5, 99, 0, 0, 189, 190, 5, 112, 0, 0, 190, 191, 5, 108, 0, 0, 191, 56, 1, 0, 0, 0, 192, 193, 5, 112, 0, 0, 193, 194, 5, 105, 0, 0, 194, 195, 5, 120, 0, 0, 195, 58, 1, 0, 0, 0, 196, 197, 5, 105, 0, 0, 197, 198, 5, 112, 0, 0, 198, 199, 5, 118, 0, 0, 199, 200, 5, 52, 0, 0, 200, 60, 1, 0, 0, 0, 201, 202, 5, 105, 0, 0, 202, 203, 5, 112, 0, 0, 203, 204, 5, 118, 0, 0, 204, 205, 5, 54, 0, 0, 205, 62, 1, 0, 0, 0, 206, 207, 5, 91, 0, 0, 207, 208, 5, 93, 0, 0, 208, 64, 1, 0, 0, 0, 209, 210, 5, 61, 0, 0, 210, 211, 5, 61, 0, 0, 211, 66, 1, 0, 0, 0, 212, 213, 5, 33, 0, 0, 213, 214, 5, 61, 0, 0, 214, 68, 1, 0, 0, 0, 215, 216, 5, 60, 0, 0, 216, 70, 1, 0, 0, 0, 217, 218, 5, 62, 0, 0, 218, 72, 1, 0, 0, 0, 219, 220, 5, 60, 0, 0, 220, 221, 5, 61, 0, 0, 221, 74, 1, 0, 0, 0, 222, 223, 5, 62, 0, 0, 223, 224, 5, 61, 0, 0, 224, 76, 1, 0, 0, 0, 225, 227, 3, 83, 41, 0, 226, 228, 3, 79, 39, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 230, 1, 0, 0, 0, 229, 231, 3, 81, 40, 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 78, 1, 0, 0, 0, 232, 234, 5, 101, 0, 0, 233, 235, 3, 95, 47, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 243, 3, 89, 44, 0, 237, 239, 5, 69, 0, 0, 238, 240, 3, 95, 47, 0, 239, 238, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 243, 3, 89, 44, 0, 242, 232, 1, 0, 0, 0, 242, 237, 1, 0, 0, 0, 243, 80, 1, 0, 0, 0, 244, 245, 7, 0, 0, 0, 245, 82, 1, 0, 0, 0, 246, 248, 3, 89, 44, 0, 247, 246, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 250, 5, 46, 0, 0, 250, 255, 3, 89, 44, 0, 251, 252, 3, 89, 44, 0, 252, 253, 5, 46, 0, 0, 253, 255, 1, 0, 0, 0, 254, 247, 1, 0, 0, 0, 254, 251, 1, 0, 0, 0, 255, 84, 1, 0, 0, 0, 256, 257, 3, 89, 44, 0, 257, 86, 1, 0, 0, 0, 258, 262, 3, 93, 46, 0, 259, 261, 3, 91, 45, 0, 260, 259, 1, 0, 0, 0, 261, 264, 1, 0, 0, 0, 262, 260, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 88, 1, 0, 0, 0, 264, 262, 1, 0, 0, 0, 265, 267, 3, 91, 45, 0, 266, 265, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 90, 1, 0, 0, 0, 270, 271, 7, 1, 0, 0, 271, 92, 1, 0, 0, 0, 272, 273, 7, 2, 0, 0, 273, 94, 1, 0, 0, 0, 274, 275, 7, 3, 0, 0, 275, 96, 1, 0, 0, 0, 276, 280, 7, 4, 0, 0, 277, 279, 7, 5, 0, 0, 278, 277, 1, 0, 0, 0, 279, 282, 1, 0, 0, 0, 280, 278, 1, 0, 0, 0, 280, 281, 1, 0, 0, 0, 281, 98, 1, 0, 0, 0, 282, 280, 1, 0, 0, 0, 283, 284, 5, 35, 0, 0, 284, 285, 5, 40, 0, 0, 285, 287, 1, 0, 0, 0, 286, 288, 8, 6, 0, 0, 287, 286, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 287, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 292, 5, 41, 0, 0, 292, 100, 1, 0, 0, 0, 293, 295, 7, 7, 0, 0, 294, 293, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 294, 1, 0, 0, 0, 296, 297, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 299, 6, 50, 0, 0, 299, 102, 1, 0, 0, 0, 300, 301, 5, 47, 0, 0, 301, 302, 5, 47, 0, 0, 302, 306, 1, 0, 0, 0, 303, 305, 9, 0, 0, 0, 304, 303, 1, 0, 0, 0, 305, 308, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 306, 304, 1, 0, 0, 0, 307, 309, 1, 0, 0, 0, 308, 306, 1, 0, 0, 0, 309, 310, 3, 105, 52, 0, 310, 311, 1, 0, 0, 0, 311, 312, 6, 51, 0, 0, 312, 104, 1, 0, 0, 0, 313, 315, 5, 13, 0, 0, 314, 313, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 317, 5, 10, 0, 0, 317, 318, 1, 0, 0, 0, 318, 319, 6, 52, 0, 0, 319, 106, 1, 0, 0, 0, 15, 0, 227, 230, 234, 239, 242, 247, 254, 262, 268, 280, 289, 296, 306, 314, 1, 6, 0, 0] \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangLexer.java b/HybroLang/.antlr/HybroLangLexer.java new file mode 100644 index 0000000..fe6b304 --- /dev/null +++ b/HybroLang/.antlr/HybroLangLexer.java @@ -0,0 +1,329 @@ +// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) +public class HybroLangLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, + T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, + T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, + T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, + DecimalFloatingConstant=39, IntegerConstant=40, DecimalConstant=41, Name=42, + INLINE=43, WhiteSpace=44, LineComment=45, NewLine=46; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", + "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", + "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", + "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", + "T__33", "T__34", "T__35", "T__36", "T__37", "DecimalFloatingConstant", + "ExponentPart", "FloatingSuffix", "FractionalConstant", "IntegerConstant", + "DecimalConstant", "DigitSequence", "Digit", "NonzeroDigit", "Sign", + "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'('", "')'", "'{'", "'}'", "','", "';'", "'for'", "'if'", "'else'", + "'return'", "'='", "'['", "']'", "'*'", "'/'", "'+'", "'-'", "'<<'", + "'>>'", "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", "'suint'", + "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", "'=='", "'!='", + "'<'", "'>'", "'<='", "'>='" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, "DecimalFloatingConstant", "IntegerConstant", "DecimalConstant", + "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public HybroLangLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "HybroLang.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\u0004\u0000.\u0140\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+ + "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+ + "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+ + "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+ + "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+ + "\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002"+ + "\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002"+ + "\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002"+ + "\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002"+ + "\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002"+ + "\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007"+ + "!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007"+ + "&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007"+ + "+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u0007"+ + "0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0001\u0000"+ + "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0003"+ + "\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0006"+ + "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+ + "\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001"+ + "\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+ + "\f\u0001\f\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+ + "\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012"+ + "\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014"+ + "\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+ + "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018"+ + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a"+ + "\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+ + "\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d"+ + "\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e"+ + "\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001"+ + " \u0001 \u0001!\u0001!\u0001!\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001"+ + "$\u0001$\u0001%\u0001%\u0001%\u0001&\u0001&\u0003&\u00e4\b&\u0001&\u0003"+ + "&\u00e7\b&\u0001\'\u0001\'\u0003\'\u00eb\b\'\u0001\'\u0001\'\u0001\'\u0003"+ + "\'\u00f0\b\'\u0001\'\u0003\'\u00f3\b\'\u0001(\u0001(\u0001)\u0003)\u00f8"+ + "\b)\u0001)\u0001)\u0001)\u0001)\u0001)\u0003)\u00ff\b)\u0001*\u0001*\u0001"+ + "+\u0001+\u0005+\u0105\b+\n+\f+\u0108\t+\u0001,\u0004,\u010b\b,\u000b,"+ + "\f,\u010c\u0001-\u0001-\u0001.\u0001.\u0001/\u0001/\u00010\u00010\u0005"+ + "0\u0117\b0\n0\f0\u011a\t0\u00011\u00011\u00011\u00011\u00041\u0120\b1"+ + "\u000b1\f1\u0121\u00011\u00011\u00012\u00042\u0127\b2\u000b2\f2\u0128"+ + "\u00012\u00012\u00013\u00013\u00013\u00013\u00053\u0131\b3\n3\f3\u0134"+ + "\t3\u00013\u00013\u00013\u00013\u00014\u00034\u013b\b4\u00014\u00014\u0001"+ + "4\u00014\u0001\u0132\u00005\u0001\u0001\u0003\u0002\u0005\u0003\u0007"+ + "\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b"+ + "\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013"+ + "\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d"+ + ";\u001e=\u001f? A!C\"E#G$I%K&M\'O\u0000Q\u0000S\u0000U(W)Y\u0000[\u0000"+ + "]\u0000_\u0000a*c+e,g-i.\u0001\u0000\b\u0004\u0000FFLLffll\u0001\u0000"+ + "09\u0001\u000019\u0002\u0000++--\u0002\u0000AZaz\u0004\u000009AZ__az\u0001"+ + "\u0000))\u0002\u0000\t\t \u0146\u0000\u0001\u0001\u0000\u0000\u0000\u0000"+ + "\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000"+ + "\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b"+ + "\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001"+ + "\u0000\u0000\u0000\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001"+ + "\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001"+ + "\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001"+ + "\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001"+ + "\u0000\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000"+ + "\u0000\u0000%\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000"+ + "\u0000)\u0001\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-"+ + "\u0001\u0000\u0000\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000"+ + "\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000"+ + "\u00007\u0001\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;"+ + "\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000"+ + "\u0000\u0000\u0000A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000"+ + "\u0000E\u0001\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0000I"+ + "\u0001\u0000\u0000\u0000\u0000K\u0001\u0000\u0000\u0000\u0000M\u0001\u0000"+ + "\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000"+ + "\u0000a\u0001\u0000\u0000\u0000\u0000c\u0001\u0000\u0000\u0000\u0000e"+ + "\u0001\u0000\u0000\u0000\u0000g\u0001\u0000\u0000\u0000\u0000i\u0001\u0000"+ + "\u0000\u0000\u0001k\u0001\u0000\u0000\u0000\u0003m\u0001\u0000\u0000\u0000"+ + "\u0005o\u0001\u0000\u0000\u0000\u0007q\u0001\u0000\u0000\u0000\ts\u0001"+ + "\u0000\u0000\u0000\u000bu\u0001\u0000\u0000\u0000\rw\u0001\u0000\u0000"+ + "\u0000\u000f{\u0001\u0000\u0000\u0000\u0011~\u0001\u0000\u0000\u0000\u0013"+ + "\u0083\u0001\u0000\u0000\u0000\u0015\u008a\u0001\u0000\u0000\u0000\u0017"+ + "\u008c\u0001\u0000\u0000\u0000\u0019\u008e\u0001\u0000\u0000\u0000\u001b"+ + "\u0090\u0001\u0000\u0000\u0000\u001d\u0092\u0001\u0000\u0000\u0000\u001f"+ + "\u0094\u0001\u0000\u0000\u0000!\u0096\u0001\u0000\u0000\u0000#\u0098\u0001"+ + "\u0000\u0000\u0000%\u009b\u0001\u0000\u0000\u0000\'\u009e\u0001\u0000"+ + "\u0000\u0000)\u00a0\u0001\u0000\u0000\u0000+\u00a2\u0001\u0000\u0000\u0000"+ + "-\u00a4\u0001\u0000\u0000\u0000/\u00a8\u0001\u0000\u0000\u00001\u00ad"+ + "\u0001\u0000\u0000\u00003\u00b2\u0001\u0000\u0000\u00005\u00b8\u0001\u0000"+ + "\u0000\u00007\u00bc\u0001\u0000\u0000\u00009\u00c0\u0001\u0000\u0000\u0000"+ + ";\u00c4\u0001\u0000\u0000\u0000=\u00c9\u0001\u0000\u0000\u0000?\u00ce"+ + "\u0001\u0000\u0000\u0000A\u00d1\u0001\u0000\u0000\u0000C\u00d4\u0001\u0000"+ + "\u0000\u0000E\u00d7\u0001\u0000\u0000\u0000G\u00d9\u0001\u0000\u0000\u0000"+ + "I\u00db\u0001\u0000\u0000\u0000K\u00de\u0001\u0000\u0000\u0000M\u00e1"+ + "\u0001\u0000\u0000\u0000O\u00f2\u0001\u0000\u0000\u0000Q\u00f4\u0001\u0000"+ + "\u0000\u0000S\u00fe\u0001\u0000\u0000\u0000U\u0100\u0001\u0000\u0000\u0000"+ + "W\u0102\u0001\u0000\u0000\u0000Y\u010a\u0001\u0000\u0000\u0000[\u010e"+ + "\u0001\u0000\u0000\u0000]\u0110\u0001\u0000\u0000\u0000_\u0112\u0001\u0000"+ + "\u0000\u0000a\u0114\u0001\u0000\u0000\u0000c\u011b\u0001\u0000\u0000\u0000"+ + "e\u0126\u0001\u0000\u0000\u0000g\u012c\u0001\u0000\u0000\u0000i\u013a"+ + "\u0001\u0000\u0000\u0000kl\u0005(\u0000\u0000l\u0002\u0001\u0000\u0000"+ + "\u0000mn\u0005)\u0000\u0000n\u0004\u0001\u0000\u0000\u0000op\u0005{\u0000"+ + "\u0000p\u0006\u0001\u0000\u0000\u0000qr\u0005}\u0000\u0000r\b\u0001\u0000"+ + "\u0000\u0000st\u0005,\u0000\u0000t\n\u0001\u0000\u0000\u0000uv\u0005;"+ + "\u0000\u0000v\f\u0001\u0000\u0000\u0000wx\u0005f\u0000\u0000xy\u0005o"+ + "\u0000\u0000yz\u0005r\u0000\u0000z\u000e\u0001\u0000\u0000\u0000{|\u0005"+ + "i\u0000\u0000|}\u0005f\u0000\u0000}\u0010\u0001\u0000\u0000\u0000~\u007f"+ + "\u0005e\u0000\u0000\u007f\u0080\u0005l\u0000\u0000\u0080\u0081\u0005s"+ + "\u0000\u0000\u0081\u0082\u0005e\u0000\u0000\u0082\u0012\u0001\u0000\u0000"+ + "\u0000\u0083\u0084\u0005r\u0000\u0000\u0084\u0085\u0005e\u0000\u0000\u0085"+ + "\u0086\u0005t\u0000\u0000\u0086\u0087\u0005u\u0000\u0000\u0087\u0088\u0005"+ + "r\u0000\u0000\u0088\u0089\u0005n\u0000\u0000\u0089\u0014\u0001\u0000\u0000"+ + "\u0000\u008a\u008b\u0005=\u0000\u0000\u008b\u0016\u0001\u0000\u0000\u0000"+ + "\u008c\u008d\u0005[\u0000\u0000\u008d\u0018\u0001\u0000\u0000\u0000\u008e"+ + "\u008f\u0005]\u0000\u0000\u008f\u001a\u0001\u0000\u0000\u0000\u0090\u0091"+ + "\u0005*\u0000\u0000\u0091\u001c\u0001\u0000\u0000\u0000\u0092\u0093\u0005"+ + "/\u0000\u0000\u0093\u001e\u0001\u0000\u0000\u0000\u0094\u0095\u0005+\u0000"+ + "\u0000\u0095 \u0001\u0000\u0000\u0000\u0096\u0097\u0005-\u0000\u0000\u0097"+ + "\"\u0001\u0000\u0000\u0000\u0098\u0099\u0005<\u0000\u0000\u0099\u009a"+ + "\u0005<\u0000\u0000\u009a$\u0001\u0000\u0000\u0000\u009b\u009c\u0005>"+ + "\u0000\u0000\u009c\u009d\u0005>\u0000\u0000\u009d&\u0001\u0000\u0000\u0000"+ + "\u009e\u009f\u0005&\u0000\u0000\u009f(\u0001\u0000\u0000\u0000\u00a0\u00a1"+ + "\u0005|\u0000\u0000\u00a1*\u0001\u0000\u0000\u0000\u00a2\u00a3\u0005^"+ + "\u0000\u0000\u00a3,\u0001\u0000\u0000\u0000\u00a4\u00a5\u0005i\u0000\u0000"+ + "\u00a5\u00a6\u0005n\u0000\u0000\u00a6\u00a7\u0005t\u0000\u0000\u00a7."+ + "\u0001\u0000\u0000\u0000\u00a8\u00a9\u0005u\u0000\u0000\u00a9\u00aa\u0005"+ + "i\u0000\u0000\u00aa\u00ab\u0005n\u0000\u0000\u00ab\u00ac\u0005t\u0000"+ + "\u0000\u00ac0\u0001\u0000\u0000\u0000\u00ad\u00ae\u0005s\u0000\u0000\u00ae"+ + "\u00af\u0005i\u0000\u0000\u00af\u00b0\u0005n\u0000\u0000\u00b0\u00b1\u0005"+ + "t\u0000\u0000\u00b12\u0001\u0000\u0000\u0000\u00b2\u00b3\u0005s\u0000"+ + "\u0000\u00b3\u00b4\u0005u\u0000\u0000\u00b4\u00b5\u0005i\u0000\u0000\u00b5"+ + "\u00b6\u0005n\u0000\u0000\u00b6\u00b7\u0005t\u0000\u0000\u00b74\u0001"+ + "\u0000\u0000\u0000\u00b8\u00b9\u0005f\u0000\u0000\u00b9\u00ba\u0005l\u0000"+ + "\u0000\u00ba\u00bb\u0005t\u0000\u0000\u00bb6\u0001\u0000\u0000\u0000\u00bc"+ + "\u00bd\u0005c\u0000\u0000\u00bd\u00be\u0005p\u0000\u0000\u00be\u00bf\u0005"+ + "l\u0000\u0000\u00bf8\u0001\u0000\u0000\u0000\u00c0\u00c1\u0005p\u0000"+ + "\u0000\u00c1\u00c2\u0005i\u0000\u0000\u00c2\u00c3\u0005x\u0000\u0000\u00c3"+ + ":\u0001\u0000\u0000\u0000\u00c4\u00c5\u0005i\u0000\u0000\u00c5\u00c6\u0005"+ + "p\u0000\u0000\u00c6\u00c7\u0005v\u0000\u0000\u00c7\u00c8\u00054\u0000"+ + "\u0000\u00c8<\u0001\u0000\u0000\u0000\u00c9\u00ca\u0005i\u0000\u0000\u00ca"+ + "\u00cb\u0005p\u0000\u0000\u00cb\u00cc\u0005v\u0000\u0000\u00cc\u00cd\u0005"+ + "6\u0000\u0000\u00cd>\u0001\u0000\u0000\u0000\u00ce\u00cf\u0005[\u0000"+ + "\u0000\u00cf\u00d0\u0005]\u0000\u0000\u00d0@\u0001\u0000\u0000\u0000\u00d1"+ + "\u00d2\u0005=\u0000\u0000\u00d2\u00d3\u0005=\u0000\u0000\u00d3B\u0001"+ + "\u0000\u0000\u0000\u00d4\u00d5\u0005!\u0000\u0000\u00d5\u00d6\u0005=\u0000"+ + "\u0000\u00d6D\u0001\u0000\u0000\u0000\u00d7\u00d8\u0005<\u0000\u0000\u00d8"+ + "F\u0001\u0000\u0000\u0000\u00d9\u00da\u0005>\u0000\u0000\u00daH\u0001"+ + "\u0000\u0000\u0000\u00db\u00dc\u0005<\u0000\u0000\u00dc\u00dd\u0005=\u0000"+ + "\u0000\u00ddJ\u0001\u0000\u0000\u0000\u00de\u00df\u0005>\u0000\u0000\u00df"+ + "\u00e0\u0005=\u0000\u0000\u00e0L\u0001\u0000\u0000\u0000\u00e1\u00e3\u0003"+ + "S)\u0000\u00e2\u00e4\u0003O\'\u0000\u00e3\u00e2\u0001\u0000\u0000\u0000"+ + "\u00e3\u00e4\u0001\u0000\u0000\u0000\u00e4\u00e6\u0001\u0000\u0000\u0000"+ + "\u00e5\u00e7\u0003Q(\u0000\u00e6\u00e5\u0001\u0000\u0000\u0000\u00e6\u00e7"+ + "\u0001\u0000\u0000\u0000\u00e7N\u0001\u0000\u0000\u0000\u00e8\u00ea\u0005"+ + "e\u0000\u0000\u00e9\u00eb\u0003_/\u0000\u00ea\u00e9\u0001\u0000\u0000"+ + "\u0000\u00ea\u00eb\u0001\u0000\u0000\u0000\u00eb\u00ec\u0001\u0000\u0000"+ + "\u0000\u00ec\u00f3\u0003Y,\u0000\u00ed\u00ef\u0005E\u0000\u0000\u00ee"+ + "\u00f0\u0003_/\u0000\u00ef\u00ee\u0001\u0000\u0000\u0000\u00ef\u00f0\u0001"+ + "\u0000\u0000\u0000\u00f0\u00f1\u0001\u0000\u0000\u0000\u00f1\u00f3\u0003"+ + "Y,\u0000\u00f2\u00e8\u0001\u0000\u0000\u0000\u00f2\u00ed\u0001\u0000\u0000"+ + "\u0000\u00f3P\u0001\u0000\u0000\u0000\u00f4\u00f5\u0007\u0000\u0000\u0000"+ + "\u00f5R\u0001\u0000\u0000\u0000\u00f6\u00f8\u0003Y,\u0000\u00f7\u00f6"+ + "\u0001\u0000\u0000\u0000\u00f7\u00f8\u0001\u0000\u0000\u0000\u00f8\u00f9"+ + "\u0001\u0000\u0000\u0000\u00f9\u00fa\u0005.\u0000\u0000\u00fa\u00ff\u0003"+ + "Y,\u0000\u00fb\u00fc\u0003Y,\u0000\u00fc\u00fd\u0005.\u0000\u0000\u00fd"+ + "\u00ff\u0001\u0000\u0000\u0000\u00fe\u00f7\u0001\u0000\u0000\u0000\u00fe"+ + "\u00fb\u0001\u0000\u0000\u0000\u00ffT\u0001\u0000\u0000\u0000\u0100\u0101"+ + "\u0003Y,\u0000\u0101V\u0001\u0000\u0000\u0000\u0102\u0106\u0003].\u0000"+ + "\u0103\u0105\u0003[-\u0000\u0104\u0103\u0001\u0000\u0000\u0000\u0105\u0108"+ + "\u0001\u0000\u0000\u0000\u0106\u0104\u0001\u0000\u0000\u0000\u0106\u0107"+ + "\u0001\u0000\u0000\u0000\u0107X\u0001\u0000\u0000\u0000\u0108\u0106\u0001"+ + "\u0000\u0000\u0000\u0109\u010b\u0003[-\u0000\u010a\u0109\u0001\u0000\u0000"+ + "\u0000\u010b\u010c\u0001\u0000\u0000\u0000\u010c\u010a\u0001\u0000\u0000"+ + "\u0000\u010c\u010d\u0001\u0000\u0000\u0000\u010dZ\u0001\u0000\u0000\u0000"+ + "\u010e\u010f\u0007\u0001\u0000\u0000\u010f\\\u0001\u0000\u0000\u0000\u0110"+ + "\u0111\u0007\u0002\u0000\u0000\u0111^\u0001\u0000\u0000\u0000\u0112\u0113"+ + "\u0007\u0003\u0000\u0000\u0113`\u0001\u0000\u0000\u0000\u0114\u0118\u0007"+ + "\u0004\u0000\u0000\u0115\u0117\u0007\u0005\u0000\u0000\u0116\u0115\u0001"+ + "\u0000\u0000\u0000\u0117\u011a\u0001\u0000\u0000\u0000\u0118\u0116\u0001"+ + "\u0000\u0000\u0000\u0118\u0119\u0001\u0000\u0000\u0000\u0119b\u0001\u0000"+ + "\u0000\u0000\u011a\u0118\u0001\u0000\u0000\u0000\u011b\u011c\u0005#\u0000"+ + "\u0000\u011c\u011d\u0005(\u0000\u0000\u011d\u011f\u0001\u0000\u0000\u0000"+ + "\u011e\u0120\b\u0006\u0000\u0000\u011f\u011e\u0001\u0000\u0000\u0000\u0120"+ + "\u0121\u0001\u0000\u0000\u0000\u0121\u011f\u0001\u0000\u0000\u0000\u0121"+ + "\u0122\u0001\u0000\u0000\u0000\u0122\u0123\u0001\u0000\u0000\u0000\u0123"+ + "\u0124\u0005)\u0000\u0000\u0124d\u0001\u0000\u0000\u0000\u0125\u0127\u0007"+ + "\u0007\u0000\u0000\u0126\u0125\u0001\u0000\u0000\u0000\u0127\u0128\u0001"+ + "\u0000\u0000\u0000\u0128\u0126\u0001\u0000\u0000\u0000\u0128\u0129\u0001"+ + "\u0000\u0000\u0000\u0129\u012a\u0001\u0000\u0000\u0000\u012a\u012b\u0006"+ + "2\u0000\u0000\u012bf\u0001\u0000\u0000\u0000\u012c\u012d\u0005/\u0000"+ + "\u0000\u012d\u012e\u0005/\u0000\u0000\u012e\u0132\u0001\u0000\u0000\u0000"+ + "\u012f\u0131\t\u0000\u0000\u0000\u0130\u012f\u0001\u0000\u0000\u0000\u0131"+ + "\u0134\u0001\u0000\u0000\u0000\u0132\u0133\u0001\u0000\u0000\u0000\u0132"+ + "\u0130\u0001\u0000\u0000\u0000\u0133\u0135\u0001\u0000\u0000\u0000\u0134"+ + "\u0132\u0001\u0000\u0000\u0000\u0135\u0136\u0003i4\u0000\u0136\u0137\u0001"+ + "\u0000\u0000\u0000\u0137\u0138\u00063\u0000\u0000\u0138h\u0001\u0000\u0000"+ + "\u0000\u0139\u013b\u0005\r\u0000\u0000\u013a\u0139\u0001\u0000\u0000\u0000"+ + "\u013a\u013b\u0001\u0000\u0000\u0000\u013b\u013c\u0001\u0000\u0000\u0000"+ + "\u013c\u013d\u0005\n\u0000\u0000\u013d\u013e\u0001\u0000\u0000\u0000\u013e"+ + "\u013f\u00064\u0000\u0000\u013fj\u0001\u0000\u0000\u0000\u000f\u0000\u00e3"+ + "\u00e6\u00ea\u00ef\u00f2\u00f7\u00fe\u0106\u010c\u0118\u0121\u0128\u0132"+ + "\u013a\u0001\u0006\u0000\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangLexer.tokens b/HybroLang/.antlr/HybroLangLexer.tokens new file mode 100644 index 0000000..574a34a --- /dev/null +++ b/HybroLang/.antlr/HybroLangLexer.tokens @@ -0,0 +1,84 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +DecimalFloatingConstant=39 +IntegerConstant=40 +DecimalConstant=41 +Name=42 +INLINE=43 +WhiteSpace=44 +LineComment=45 +NewLine=46 +'('=1 +')'=2 +'{'=3 +'}'=4 +','=5 +';'=6 +'for'=7 +'if'=8 +'else'=9 +'return'=10 +'='=11 +'['=12 +']'=13 +'*'=14 +'/'=15 +'+'=16 +'-'=17 +'<<'=18 +'>>'=19 +'&'=20 +'|'=21 +'^'=22 +'int'=23 +'uint'=24 +'sint'=25 +'suint'=26 +'flt'=27 +'cpl'=28 +'pix'=29 +'ipv4'=30 +'ipv6'=31 +'[]'=32 +'=='=33 +'!='=34 +'<'=35 +'>'=36 +'<='=37 +'>='=38 diff --git a/HybroLang/.antlr/HybroLangListener.java b/HybroLang/.antlr/HybroLangListener.java new file mode 100644 index 0000000..17c0a14 --- /dev/null +++ b/HybroLang/.antlr/HybroLangListener.java @@ -0,0 +1,255 @@ +// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link HybroLangParser}. + */ +public interface HybroLangListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link HybroLangParser#compilationunit}. + * @param ctx the parse tree + */ + void enterCompilationunit(HybroLangParser.CompilationunitContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#compilationunit}. + * @param ctx the parse tree + */ + void exitCompilationunit(HybroLangParser.CompilationunitContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#function}. + * @param ctx the parse tree + */ + void enterFunction(HybroLangParser.FunctionContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#function}. + * @param ctx the parse tree + */ + void exitFunction(HybroLangParser.FunctionContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#fndcl}. + * @param ctx the parse tree + */ + void enterFndcl(HybroLangParser.FndclContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#fndcl}. + * @param ctx the parse tree + */ + void exitFndcl(HybroLangParser.FndclContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#fnprototype}. + * @param ctx the parse tree + */ + void enterFnprototype(HybroLangParser.FnprototypeContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#fnprototype}. + * @param ctx the parse tree + */ + void exitFnprototype(HybroLangParser.FnprototypeContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#fnbody}. + * @param ctx the parse tree + */ + void enterFnbody(HybroLangParser.FnbodyContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#fnbody}. + * @param ctx the parse tree + */ + void exitFnbody(HybroLangParser.FnbodyContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#paramdcllist}. + * @param ctx the parse tree + */ + void enterParamdcllist(HybroLangParser.ParamdcllistContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#paramdcllist}. + * @param ctx the parse tree + */ + void exitParamdcllist(HybroLangParser.ParamdcllistContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#localvardef}. + * @param ctx the parse tree + */ + void enterLocalvardef(HybroLangParser.LocalvardefContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#localvardef}. + * @param ctx the parse tree + */ + void exitLocalvardef(HybroLangParser.LocalvardefContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#vardcllist}. + * @param ctx the parse tree + */ + void enterVardcllist(HybroLangParser.VardcllistContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#vardcllist}. + * @param ctx the parse tree + */ + void exitVardcllist(HybroLangParser.VardcllistContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#vardcl}. + * @param ctx the parse tree + */ + void enterVardcl(HybroLangParser.VardclContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#vardcl}. + * @param ctx the parse tree + */ + void exitVardcl(HybroLangParser.VardclContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#actionlist}. + * @param ctx the parse tree + */ + void enterActionlist(HybroLangParser.ActionlistContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#actionlist}. + * @param ctx the parse tree + */ + void exitActionlist(HybroLangParser.ActionlistContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#condexpr}. + * @param ctx the parse tree + */ + void enterCondexpr(HybroLangParser.CondexprContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#condexpr}. + * @param ctx the parse tree + */ + void exitCondexpr(HybroLangParser.CondexprContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#action}. + * @param ctx the parse tree + */ + void enterAction(HybroLangParser.ActionContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#action}. + * @param ctx the parse tree + */ + void exitAction(HybroLangParser.ActionContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#returnexpr}. + * @param ctx the parse tree + */ + void enterReturnexpr(HybroLangParser.ReturnexprContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#returnexpr}. + * @param ctx the parse tree + */ + void exitReturnexpr(HybroLangParser.ReturnexprContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#affectexpr}. + * @param ctx the parse tree + */ + void enterAffectexpr(HybroLangParser.AffectexprContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#affectexpr}. + * @param ctx the parse tree + */ + void exitAffectexpr(HybroLangParser.AffectexprContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#unaryexpr}. + * @param ctx the parse tree + */ + void enterUnaryexpr(HybroLangParser.UnaryexprContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#unaryexpr}. + * @param ctx the parse tree + */ + void exitUnaryexpr(HybroLangParser.UnaryexprContext ctx); + /** + * Enter a parse tree produced by the {@code varorvalueArray} + * labeled alternative in {@link HybroLangParser#varorvalue}. + * @param ctx the parse tree + */ + void enterVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx); + /** + * Exit a parse tree produced by the {@code varorvalueArray} + * labeled alternative in {@link HybroLangParser#varorvalue}. + * @param ctx the parse tree + */ + void exitVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx); + /** + * Enter a parse tree produced by the {@code varorvalueConst} + * labeled alternative in {@link HybroLangParser#varorvalue}. + * @param ctx the parse tree + */ + void enterVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx); + /** + * Exit a parse tree produced by the {@code varorvalueConst} + * labeled alternative in {@link HybroLangParser#varorvalue}. + * @param ctx the parse tree + */ + void exitVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx); + /** + * Enter a parse tree produced by the {@code varorvalueVar} + * labeled alternative in {@link HybroLangParser#varorvalue}. + * @param ctx the parse tree + */ + void enterVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx); + /** + * Exit a parse tree produced by the {@code varorvalueVar} + * labeled alternative in {@link HybroLangParser#varorvalue}. + * @param ctx the parse tree + */ + void exitVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#datatype}. + * @param ctx the parse tree + */ + void enterDatatype(HybroLangParser.DatatypeContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#datatype}. + * @param ctx the parse tree + */ + void exitDatatype(HybroLangParser.DatatypeContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#intconstvalue}. + * @param ctx the parse tree + */ + void enterIntconstvalue(HybroLangParser.IntconstvalueContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#intconstvalue}. + * @param ctx the parse tree + */ + void exitIntconstvalue(HybroLangParser.IntconstvalueContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#constvalue}. + * @param ctx the parse tree + */ + void enterConstvalue(HybroLangParser.ConstvalueContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#constvalue}. + * @param ctx the parse tree + */ + void exitConstvalue(HybroLangParser.ConstvalueContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#constinline}. + * @param ctx the parse tree + */ + void enterConstinline(HybroLangParser.ConstinlineContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#constinline}. + * @param ctx the parse tree + */ + void exitConstinline(HybroLangParser.ConstinlineContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#typebase}. + * @param ctx the parse tree + */ + void enterTypebase(HybroLangParser.TypebaseContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#typebase}. + * @param ctx the parse tree + */ + void exitTypebase(HybroLangParser.TypebaseContext ctx); + /** + * Enter a parse tree produced by {@link HybroLangParser#condOperator}. + * @param ctx the parse tree + */ + void enterCondOperator(HybroLangParser.CondOperatorContext ctx); + /** + * Exit a parse tree produced by {@link HybroLangParser#condOperator}. + * @param ctx the parse tree + */ + void exitCondOperator(HybroLangParser.CondOperatorContext ctx); +} \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangParser.java b/HybroLang/.antlr/HybroLangParser.java new file mode 100644 index 0000000..784d4f0 --- /dev/null +++ b/HybroLang/.antlr/HybroLangParser.java @@ -0,0 +1,1680 @@ +// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class HybroLangParser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, + T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, + T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, + T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, + DecimalFloatingConstant=39, IntegerConstant=40, DecimalConstant=41, Name=42, + INLINE=43, WhiteSpace=44, LineComment=45, NewLine=46; + public static final int + RULE_compilationunit = 0, RULE_function = 1, RULE_fndcl = 2, RULE_fnprototype = 3, + RULE_fnbody = 4, RULE_paramdcllist = 5, RULE_localvardef = 6, RULE_vardcllist = 7, + RULE_vardcl = 8, RULE_actionlist = 9, RULE_condexpr = 10, RULE_action = 11, + RULE_returnexpr = 12, RULE_affectexpr = 13, RULE_unaryexpr = 14, RULE_varorvalue = 15, + RULE_datatype = 16, RULE_intconstvalue = 17, RULE_constvalue = 18, RULE_constinline = 19, + RULE_typebase = 20, RULE_condOperator = 21; + private static String[] makeRuleNames() { + return new String[] { + "compilationunit", "function", "fndcl", "fnprototype", "fnbody", "paramdcllist", + "localvardef", "vardcllist", "vardcl", "actionlist", "condexpr", "action", + "returnexpr", "affectexpr", "unaryexpr", "varorvalue", "datatype", "intconstvalue", + "constvalue", "constinline", "typebase", "condOperator" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'('", "')'", "'{'", "'}'", "','", "';'", "'for'", "'if'", "'else'", + "'return'", "'='", "'['", "']'", "'*'", "'/'", "'+'", "'-'", "'<<'", + "'>>'", "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", "'suint'", + "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", "'=='", "'!='", + "'<'", "'>'", "'<='", "'>='" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, "DecimalFloatingConstant", "IntegerConstant", "DecimalConstant", + "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "HybroLang.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public HybroLangParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class CompilationunitContext extends ParserRuleContext { + public List function() { + return getRuleContexts(FunctionContext.class); + } + public FunctionContext function(int i) { + return getRuleContext(FunctionContext.class,i); + } + public CompilationunitContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_compilationunit; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterCompilationunit(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitCompilationunit(this); + } + } + + public final CompilationunitContext compilationunit() throws RecognitionException { + CompilationunitContext _localctx = new CompilationunitContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_compilationunit); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(45); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(44); + function(); + } + } + setState(47); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & 4286578688L) != 0) ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FunctionContext extends ParserRuleContext { + public FndclContext fndcl() { + return getRuleContext(FndclContext.class,0); + } + public FnbodyContext fnbody() { + return getRuleContext(FnbodyContext.class,0); + } + public FunctionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_function; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFunction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFunction(this); + } + } + + public final FunctionContext function() throws RecognitionException { + FunctionContext _localctx = new FunctionContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_function); + try { + enterOuterAlt(_localctx, 1); + { + setState(49); + fndcl(); + setState(50); + fnbody(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FndclContext extends ParserRuleContext { + public DatatypeContext datatype() { + return getRuleContext(DatatypeContext.class,0); + } + public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } + public FnprototypeContext fnprototype() { + return getRuleContext(FnprototypeContext.class,0); + } + public FndclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fndcl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFndcl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFndcl(this); + } + } + + public final FndclContext fndcl() throws RecognitionException { + FndclContext _localctx = new FndclContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_fndcl); + try { + enterOuterAlt(_localctx, 1); + { + setState(52); + datatype(); + setState(53); + match(Name); + setState(54); + fnprototype(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FnprototypeContext extends ParserRuleContext { + public ParamdcllistContext paramdcllist() { + return getRuleContext(ParamdcllistContext.class,0); + } + public FnprototypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fnprototype; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFnprototype(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFnprototype(this); + } + } + + public final FnprototypeContext fnprototype() throws RecognitionException { + FnprototypeContext _localctx = new FnprototypeContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_fnprototype); + try { + enterOuterAlt(_localctx, 1); + { + setState(56); + match(T__0); + setState(57); + paramdcllist(); + setState(58); + match(T__1); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class FnbodyContext extends ParserRuleContext { + public ActionlistContext actionlist() { + return getRuleContext(ActionlistContext.class,0); + } + public List localvardef() { + return getRuleContexts(LocalvardefContext.class); + } + public LocalvardefContext localvardef(int i) { + return getRuleContext(LocalvardefContext.class,i); + } + public ReturnexprContext returnexpr() { + return getRuleContext(ReturnexprContext.class,0); + } + public FnbodyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fnbody; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFnbody(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFnbody(this); + } + } + + public final FnbodyContext fnbody() throws RecognitionException { + FnbodyContext _localctx = new FnbodyContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_fnbody); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(60); + match(T__2); + setState(64); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 4286578688L) != 0)) { + { + { + setState(61); + localvardef(); + } + } + setState(66); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(67); + actionlist(); + setState(69); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__9) { + { + setState(68); + returnexpr(); + } + } + + setState(71); + match(T__3); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ParamdcllistContext extends ParserRuleContext { + public List vardcl() { + return getRuleContexts(VardclContext.class); + } + public VardclContext vardcl(int i) { + return getRuleContext(VardclContext.class,i); + } + public ParamdcllistContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_paramdcllist; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterParamdcllist(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitParamdcllist(this); + } + } + + public final ParamdcllistContext paramdcllist() throws RecognitionException { + ParamdcllistContext _localctx = new ParamdcllistContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_paramdcllist); + int _la; + try { + setState(82); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__22: + case T__23: + case T__24: + case T__25: + case T__26: + case T__27: + case T__28: + case T__29: + case T__30: + enterOuterAlt(_localctx, 1); + { + setState(73); + vardcl(); + setState(78); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__4) { + { + { + setState(74); + match(T__4); + setState(75); + vardcl(); + } + } + setState(80); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + case T__1: + enterOuterAlt(_localctx, 2); + { + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class LocalvardefContext extends ParserRuleContext { + public VardcllistContext vardcllist() { + return getRuleContext(VardcllistContext.class,0); + } + public LocalvardefContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_localvardef; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterLocalvardef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitLocalvardef(this); + } + } + + public final LocalvardefContext localvardef() throws RecognitionException { + LocalvardefContext _localctx = new LocalvardefContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_localvardef); + try { + enterOuterAlt(_localctx, 1); + { + setState(84); + vardcllist(); + setState(85); + match(T__5); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class VardcllistContext extends ParserRuleContext { + public VardclContext vardcl() { + return getRuleContext(VardclContext.class,0); + } + public List Name() { return getTokens(HybroLangParser.Name); } + public TerminalNode Name(int i) { + return getToken(HybroLangParser.Name, i); + } + public VardcllistContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_vardcllist; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVardcllist(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVardcllist(this); + } + } + + public final VardcllistContext vardcllist() throws RecognitionException { + VardcllistContext _localctx = new VardcllistContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_vardcllist); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(87); + vardcl(); + setState(92); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__4) { + { + { + setState(88); + match(T__4); + setState(89); + match(Name); + } + } + setState(94); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class VardclContext extends ParserRuleContext { + public DatatypeContext datatype() { + return getRuleContext(DatatypeContext.class,0); + } + public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } + public VardclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_vardcl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVardcl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVardcl(this); + } + } + + public final VardclContext vardcl() throws RecognitionException { + VardclContext _localctx = new VardclContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_vardcl); + try { + enterOuterAlt(_localctx, 1); + { + setState(95); + datatype(); + setState(96); + match(Name); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ActionlistContext extends ParserRuleContext { + public List action() { + return getRuleContexts(ActionContext.class); + } + public ActionContext action(int i) { + return getRuleContext(ActionContext.class,i); + } + public ActionlistContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_actionlist; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterActionlist(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitActionlist(this); + } + } + + public final ActionlistContext actionlist() throws RecognitionException { + ActionlistContext _localctx = new ActionlistContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_actionlist); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(101); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 4398046511488L) != 0)) { + { + { + setState(98); + action(); + } + } + setState(103); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class CondexprContext extends ParserRuleContext { + public List varorvalue() { + return getRuleContexts(VarorvalueContext.class); + } + public VarorvalueContext varorvalue(int i) { + return getRuleContext(VarorvalueContext.class,i); + } + public CondOperatorContext condOperator() { + return getRuleContext(CondOperatorContext.class,0); + } + public CondexprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_condexpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterCondexpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitCondexpr(this); + } + } + + public final CondexprContext condexpr() throws RecognitionException { + CondexprContext _localctx = new CondexprContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_condexpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(104); + varorvalue(); + setState(105); + condOperator(); + setState(106); + varorvalue(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ActionContext extends ParserRuleContext { + public List affectexpr() { + return getRuleContexts(AffectexprContext.class); + } + public AffectexprContext affectexpr(int i) { + return getRuleContext(AffectexprContext.class,i); + } + public CondexprContext condexpr() { + return getRuleContext(CondexprContext.class,0); + } + public List actionlist() { + return getRuleContexts(ActionlistContext.class); + } + public ActionlistContext actionlist(int i) { + return getRuleContext(ActionlistContext.class,i); + } + public ActionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_action; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterAction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitAction(this); + } + } + + public final ActionContext action() throws RecognitionException { + ActionContext _localctx = new ActionContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_action); + try { + setState(135); + _errHandler.sync(this); + switch (_input.LA(1)) { + case Name: + enterOuterAlt(_localctx, 1); + { + setState(108); + affectexpr(); + setState(109); + match(T__5); + } + break; + case T__6: + enterOuterAlt(_localctx, 2); + { + setState(111); + match(T__6); + setState(112); + match(T__0); + setState(113); + affectexpr(); + setState(114); + match(T__5); + setState(115); + condexpr(); + setState(116); + match(T__5); + setState(117); + affectexpr(); + setState(118); + match(T__1); + setState(119); + match(T__2); + setState(120); + actionlist(); + setState(121); + match(T__3); + } + break; + case T__7: + enterOuterAlt(_localctx, 3); + { + setState(123); + match(T__7); + setState(124); + match(T__0); + setState(125); + condexpr(); + setState(126); + match(T__1); + setState(127); + match(T__2); + setState(128); + actionlist(); + setState(129); + match(T__3); + setState(130); + match(T__8); + setState(131); + match(T__2); + setState(132); + actionlist(); + setState(133); + match(T__3); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ReturnexprContext extends ParserRuleContext { + public UnaryexprContext unaryexpr() { + return getRuleContext(UnaryexprContext.class,0); + } + public ReturnexprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_returnexpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterReturnexpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitReturnexpr(this); + } + } + + public final ReturnexprContext returnexpr() throws RecognitionException { + ReturnexprContext _localctx = new ReturnexprContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_returnexpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(137); + match(T__9); + setState(138); + unaryexpr(0); + setState(139); + match(T__5); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class AffectexprContext extends ParserRuleContext { + public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } + public List unaryexpr() { + return getRuleContexts(UnaryexprContext.class); + } + public UnaryexprContext unaryexpr(int i) { + return getRuleContext(UnaryexprContext.class,i); + } + public AffectexprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_affectexpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterAffectexpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitAffectexpr(this); + } + } + + public final AffectexprContext affectexpr() throws RecognitionException { + AffectexprContext _localctx = new AffectexprContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_affectexpr); + try { + setState(151); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(141); + match(Name); + setState(142); + match(T__10); + setState(143); + unaryexpr(0); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(144); + match(Name); + setState(145); + match(T__11); + setState(146); + unaryexpr(0); + setState(147); + match(T__12); + setState(148); + match(T__10); + setState(149); + unaryexpr(0); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class UnaryexprContext extends ParserRuleContext { + public Token op; + public VarorvalueContext varorvalue() { + return getRuleContext(VarorvalueContext.class,0); + } + public List unaryexpr() { + return getRuleContexts(UnaryexprContext.class); + } + public UnaryexprContext unaryexpr(int i) { + return getRuleContext(UnaryexprContext.class,i); + } + public UnaryexprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_unaryexpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterUnaryexpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitUnaryexpr(this); + } + } + + public final UnaryexprContext unaryexpr() throws RecognitionException { + return unaryexpr(0); + } + + private UnaryexprContext unaryexpr(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + UnaryexprContext _localctx = new UnaryexprContext(_ctx, _parentState); + UnaryexprContext _prevctx = _localctx; + int _startState = 28; + enterRecursionRule(_localctx, 28, RULE_unaryexpr, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + { + setState(154); + varorvalue(); + } + _ctx.stop = _input.LT(-1); + setState(170); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(168); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { + case 1: + { + _localctx = new UnaryexprContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); + setState(156); + if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); + setState(157); + ((UnaryexprContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==T__13 || _la==T__14) ) { + ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(158); + unaryexpr(6); + } + break; + case 2: + { + _localctx = new UnaryexprContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); + setState(159); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(160); + ((UnaryexprContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==T__15 || _la==T__16) ) { + ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(161); + unaryexpr(5); + } + break; + case 3: + { + _localctx = new UnaryexprContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); + setState(162); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(163); + ((UnaryexprContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==T__17 || _la==T__18) ) { + ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(164); + unaryexpr(4); + } + break; + case 4: + { + _localctx = new UnaryexprContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); + setState(165); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(166); + ((UnaryexprContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 7340032L) != 0)) ) { + ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(167); + unaryexpr(3); + } + break; + } + } + } + setState(172); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class VarorvalueContext extends ParserRuleContext { + public VarorvalueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_varorvalue; } + + public VarorvalueContext() { } + public void copyFrom(VarorvalueContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class VarorvalueVarContext extends VarorvalueContext { + public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } + public VarorvalueVarContext(VarorvalueContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVarorvalueVar(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVarorvalueVar(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class VarorvalueArrayContext extends VarorvalueContext { + public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } + public UnaryexprContext unaryexpr() { + return getRuleContext(UnaryexprContext.class,0); + } + public VarorvalueArrayContext(VarorvalueContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVarorvalueArray(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVarorvalueArray(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class VarorvalueConstContext extends VarorvalueContext { + public ConstvalueContext constvalue() { + return getRuleContext(ConstvalueContext.class,0); + } + public VarorvalueConstContext(VarorvalueContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVarorvalueConst(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVarorvalueConst(this); + } + } + + public final VarorvalueContext varorvalue() throws RecognitionException { + VarorvalueContext _localctx = new VarorvalueContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_varorvalue); + try { + setState(180); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { + case 1: + _localctx = new VarorvalueArrayContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(173); + match(Name); + setState(174); + match(T__11); + setState(175); + unaryexpr(0); + setState(176); + match(T__12); + } + break; + case 2: + _localctx = new VarorvalueConstContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(178); + constvalue(); + } + break; + case 3: + _localctx = new VarorvalueVarContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(179); + match(Name); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DatatypeContext extends ParserRuleContext { + public IntconstvalueContext wordlen; + public IntconstvalueContext vectorlen; + public TypebaseContext typebase() { + return getRuleContext(TypebaseContext.class,0); + } + public List intconstvalue() { + return getRuleContexts(IntconstvalueContext.class); + } + public IntconstvalueContext intconstvalue(int i) { + return getRuleContext(IntconstvalueContext.class,i); + } + public DatatypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_datatype; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterDatatype(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitDatatype(this); + } + } + + public final DatatypeContext datatype() throws RecognitionException { + DatatypeContext _localctx = new DatatypeContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_datatype); + try { + enterOuterAlt(_localctx, 1); + { + setState(182); + typebase(); + setState(183); + ((DatatypeContext)_localctx).wordlen = intconstvalue(); + setState(184); + ((DatatypeContext)_localctx).vectorlen = intconstvalue(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class IntconstvalueContext extends ParserRuleContext { + public TerminalNode IntegerConstant() { return getToken(HybroLangParser.IntegerConstant, 0); } + public ConstinlineContext constinline() { + return getRuleContext(ConstinlineContext.class,0); + } + public IntconstvalueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_intconstvalue; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterIntconstvalue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitIntconstvalue(this); + } + } + + public final IntconstvalueContext intconstvalue() throws RecognitionException { + IntconstvalueContext _localctx = new IntconstvalueContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_intconstvalue); + try { + setState(188); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IntegerConstant: + enterOuterAlt(_localctx, 1); + { + setState(186); + match(IntegerConstant); + } + break; + case INLINE: + enterOuterAlt(_localctx, 2); + { + setState(187); + constinline(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ConstvalueContext extends ParserRuleContext { + public TerminalNode IntegerConstant() { return getToken(HybroLangParser.IntegerConstant, 0); } + public TerminalNode DecimalFloatingConstant() { return getToken(HybroLangParser.DecimalFloatingConstant, 0); } + public ConstinlineContext constinline() { + return getRuleContext(ConstinlineContext.class,0); + } + public ConstvalueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constvalue; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterConstvalue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitConstvalue(this); + } + } + + public final ConstvalueContext constvalue() throws RecognitionException { + ConstvalueContext _localctx = new ConstvalueContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_constvalue); + try { + setState(193); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IntegerConstant: + enterOuterAlt(_localctx, 1); + { + setState(190); + match(IntegerConstant); + } + break; + case DecimalFloatingConstant: + enterOuterAlt(_localctx, 2); + { + setState(191); + match(DecimalFloatingConstant); + } + break; + case INLINE: + enterOuterAlt(_localctx, 3); + { + setState(192); + constinline(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class ConstinlineContext extends ParserRuleContext { + public TerminalNode INLINE() { return getToken(HybroLangParser.INLINE, 0); } + public ConstinlineContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constinline; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterConstinline(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitConstinline(this); + } + } + + public final ConstinlineContext constinline() throws RecognitionException { + ConstinlineContext _localctx = new ConstinlineContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_constinline); + try { + enterOuterAlt(_localctx, 1); + { + setState(195); + match(INLINE); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class TypebaseContext extends ParserRuleContext { + public TypebaseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typebase; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterTypebase(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitTypebase(this); + } + } + + public final TypebaseContext typebase() throws RecognitionException { + TypebaseContext _localctx = new TypebaseContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_typebase); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(197); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 4286578688L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(199); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__31) { + { + setState(198); + match(T__31); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class CondOperatorContext extends ParserRuleContext { + public CondOperatorContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_condOperator; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterCondOperator(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitCondOperator(this); + } + } + + public final CondOperatorContext condOperator() throws RecognitionException { + CondOperatorContext _localctx = new CondOperatorContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_condOperator); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(201); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 541165879296L) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 14: + return unaryexpr_sempred((UnaryexprContext)_localctx, predIndex); + } + return true; + } + private boolean unaryexpr_sempred(UnaryexprContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 5); + case 1: + return precpred(_ctx, 4); + case 2: + return precpred(_ctx, 3); + case 3: + return precpred(_ctx, 2); + } + return true; + } + + public static final String _serializedATN = + "\u0004\u0001.\u00cc\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ + "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ + "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ + "\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007\u000f"+ + "\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007\u0012"+ + "\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007\u0015"+ + "\u0001\u0000\u0004\u0000.\b\u0000\u000b\u0000\f\u0000/\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+ + "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0005"+ + "\u0004?\b\u0004\n\u0004\f\u0004B\t\u0004\u0001\u0004\u0001\u0004\u0003"+ + "\u0004F\b\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001"+ + "\u0005\u0005\u0005M\b\u0005\n\u0005\f\u0005P\t\u0005\u0001\u0005\u0003"+ + "\u0005S\b\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001"+ + "\u0007\u0001\u0007\u0005\u0007[\b\u0007\n\u0007\f\u0007^\t\u0007\u0001"+ + "\b\u0001\b\u0001\b\u0001\t\u0005\td\b\t\n\t\f\tg\t\t\u0001\n\u0001\n\u0001"+ + "\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ + "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0003\u000b\u0088\b\u000b"+ + "\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ + "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0003\r\u0098\b\r\u0001\u000e"+ + "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ + "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ + "\u0001\u000e\u0001\u000e\u0005\u000e\u00a9\b\u000e\n\u000e\f\u000e\u00ac"+ + "\t\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+ + "\u000f\u0001\u000f\u0003\u000f\u00b5\b\u000f\u0001\u0010\u0001\u0010\u0001"+ + "\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0003\u0011\u00bd\b\u0011\u0001"+ + "\u0012\u0001\u0012\u0001\u0012\u0003\u0012\u00c2\b\u0012\u0001\u0013\u0001"+ + "\u0013\u0001\u0014\u0001\u0014\u0003\u0014\u00c8\b\u0014\u0001\u0015\u0001"+ + "\u0015\u0001\u0015\u0000\u0001\u001c\u0016\u0000\u0002\u0004\u0006\b\n"+ + "\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*\u0000"+ + "\u0006\u0001\u0000\u000e\u000f\u0001\u0000\u0010\u0011\u0001\u0000\u0012"+ + "\u0013\u0001\u0000\u0014\u0016\u0001\u0000\u0017\u001f\u0001\u0000!&\u00c9"+ + "\u0000-\u0001\u0000\u0000\u0000\u00021\u0001\u0000\u0000\u0000\u00044"+ + "\u0001\u0000\u0000\u0000\u00068\u0001\u0000\u0000\u0000\b<\u0001\u0000"+ + "\u0000\u0000\nR\u0001\u0000\u0000\u0000\fT\u0001\u0000\u0000\u0000\u000e"+ + "W\u0001\u0000\u0000\u0000\u0010_\u0001\u0000\u0000\u0000\u0012e\u0001"+ + "\u0000\u0000\u0000\u0014h\u0001\u0000\u0000\u0000\u0016\u0087\u0001\u0000"+ + "\u0000\u0000\u0018\u0089\u0001\u0000\u0000\u0000\u001a\u0097\u0001\u0000"+ + "\u0000\u0000\u001c\u0099\u0001\u0000\u0000\u0000\u001e\u00b4\u0001\u0000"+ + "\u0000\u0000 \u00b6\u0001\u0000\u0000\u0000\"\u00bc\u0001\u0000\u0000"+ + "\u0000$\u00c1\u0001\u0000\u0000\u0000&\u00c3\u0001\u0000\u0000\u0000("+ + "\u00c5\u0001\u0000\u0000\u0000*\u00c9\u0001\u0000\u0000\u0000,.\u0003"+ + "\u0002\u0001\u0000-,\u0001\u0000\u0000\u0000./\u0001\u0000\u0000\u0000"+ + "/-\u0001\u0000\u0000\u0000/0\u0001\u0000\u0000\u00000\u0001\u0001\u0000"+ + "\u0000\u000012\u0003\u0004\u0002\u000023\u0003\b\u0004\u00003\u0003\u0001"+ + "\u0000\u0000\u000045\u0003 \u0010\u000056\u0005*\u0000\u000067\u0003\u0006"+ + "\u0003\u00007\u0005\u0001\u0000\u0000\u000089\u0005\u0001\u0000\u0000"+ + "9:\u0003\n\u0005\u0000:;\u0005\u0002\u0000\u0000;\u0007\u0001\u0000\u0000"+ + "\u0000<@\u0005\u0003\u0000\u0000=?\u0003\f\u0006\u0000>=\u0001\u0000\u0000"+ + "\u0000?B\u0001\u0000\u0000\u0000@>\u0001\u0000\u0000\u0000@A\u0001\u0000"+ + "\u0000\u0000AC\u0001\u0000\u0000\u0000B@\u0001\u0000\u0000\u0000CE\u0003"+ + "\u0012\t\u0000DF\u0003\u0018\f\u0000ED\u0001\u0000\u0000\u0000EF\u0001"+ + "\u0000\u0000\u0000FG\u0001\u0000\u0000\u0000GH\u0005\u0004\u0000\u0000"+ + "H\t\u0001\u0000\u0000\u0000IN\u0003\u0010\b\u0000JK\u0005\u0005\u0000"+ + "\u0000KM\u0003\u0010\b\u0000LJ\u0001\u0000\u0000\u0000MP\u0001\u0000\u0000"+ + "\u0000NL\u0001\u0000\u0000\u0000NO\u0001\u0000\u0000\u0000OS\u0001\u0000"+ + "\u0000\u0000PN\u0001\u0000\u0000\u0000QS\u0001\u0000\u0000\u0000RI\u0001"+ + "\u0000\u0000\u0000RQ\u0001\u0000\u0000\u0000S\u000b\u0001\u0000\u0000"+ + "\u0000TU\u0003\u000e\u0007\u0000UV\u0005\u0006\u0000\u0000V\r\u0001\u0000"+ + "\u0000\u0000W\\\u0003\u0010\b\u0000XY\u0005\u0005\u0000\u0000Y[\u0005"+ + "*\u0000\u0000ZX\u0001\u0000\u0000\u0000[^\u0001\u0000\u0000\u0000\\Z\u0001"+ + "\u0000\u0000\u0000\\]\u0001\u0000\u0000\u0000]\u000f\u0001\u0000\u0000"+ + "\u0000^\\\u0001\u0000\u0000\u0000_`\u0003 \u0010\u0000`a\u0005*\u0000"+ + "\u0000a\u0011\u0001\u0000\u0000\u0000bd\u0003\u0016\u000b\u0000cb\u0001"+ + "\u0000\u0000\u0000dg\u0001\u0000\u0000\u0000ec\u0001\u0000\u0000\u0000"+ + "ef\u0001\u0000\u0000\u0000f\u0013\u0001\u0000\u0000\u0000ge\u0001\u0000"+ + "\u0000\u0000hi\u0003\u001e\u000f\u0000ij\u0003*\u0015\u0000jk\u0003\u001e"+ + "\u000f\u0000k\u0015\u0001\u0000\u0000\u0000lm\u0003\u001a\r\u0000mn\u0005"+ + "\u0006\u0000\u0000n\u0088\u0001\u0000\u0000\u0000op\u0005\u0007\u0000"+ + "\u0000pq\u0005\u0001\u0000\u0000qr\u0003\u001a\r\u0000rs\u0005\u0006\u0000"+ + "\u0000st\u0003\u0014\n\u0000tu\u0005\u0006\u0000\u0000uv\u0003\u001a\r"+ + "\u0000vw\u0005\u0002\u0000\u0000wx\u0005\u0003\u0000\u0000xy\u0003\u0012"+ + "\t\u0000yz\u0005\u0004\u0000\u0000z\u0088\u0001\u0000\u0000\u0000{|\u0005"+ + "\b\u0000\u0000|}\u0005\u0001\u0000\u0000}~\u0003\u0014\n\u0000~\u007f"+ + "\u0005\u0002\u0000\u0000\u007f\u0080\u0005\u0003\u0000\u0000\u0080\u0081"+ + "\u0003\u0012\t\u0000\u0081\u0082\u0005\u0004\u0000\u0000\u0082\u0083\u0005"+ + "\t\u0000\u0000\u0083\u0084\u0005\u0003\u0000\u0000\u0084\u0085\u0003\u0012"+ + "\t\u0000\u0085\u0086\u0005\u0004\u0000\u0000\u0086\u0088\u0001\u0000\u0000"+ + "\u0000\u0087l\u0001\u0000\u0000\u0000\u0087o\u0001\u0000\u0000\u0000\u0087"+ + "{\u0001\u0000\u0000\u0000\u0088\u0017\u0001\u0000\u0000\u0000\u0089\u008a"+ + "\u0005\n\u0000\u0000\u008a\u008b\u0003\u001c\u000e\u0000\u008b\u008c\u0005"+ + "\u0006\u0000\u0000\u008c\u0019\u0001\u0000\u0000\u0000\u008d\u008e\u0005"+ + "*\u0000\u0000\u008e\u008f\u0005\u000b\u0000\u0000\u008f\u0098\u0003\u001c"+ + "\u000e\u0000\u0090\u0091\u0005*\u0000\u0000\u0091\u0092\u0005\f\u0000"+ + "\u0000\u0092\u0093\u0003\u001c\u000e\u0000\u0093\u0094\u0005\r\u0000\u0000"+ + "\u0094\u0095\u0005\u000b\u0000\u0000\u0095\u0096\u0003\u001c\u000e\u0000"+ + "\u0096\u0098\u0001\u0000\u0000\u0000\u0097\u008d\u0001\u0000\u0000\u0000"+ + "\u0097\u0090\u0001\u0000\u0000\u0000\u0098\u001b\u0001\u0000\u0000\u0000"+ + "\u0099\u009a\u0006\u000e\uffff\uffff\u0000\u009a\u009b\u0003\u001e\u000f"+ + "\u0000\u009b\u00aa\u0001\u0000\u0000\u0000\u009c\u009d\n\u0005\u0000\u0000"+ + "\u009d\u009e\u0007\u0000\u0000\u0000\u009e\u00a9\u0003\u001c\u000e\u0006"+ + "\u009f\u00a0\n\u0004\u0000\u0000\u00a0\u00a1\u0007\u0001\u0000\u0000\u00a1"+ + "\u00a9\u0003\u001c\u000e\u0005\u00a2\u00a3\n\u0003\u0000\u0000\u00a3\u00a4"+ + "\u0007\u0002\u0000\u0000\u00a4\u00a9\u0003\u001c\u000e\u0004\u00a5\u00a6"+ + "\n\u0002\u0000\u0000\u00a6\u00a7\u0007\u0003\u0000\u0000\u00a7\u00a9\u0003"+ + "\u001c\u000e\u0003\u00a8\u009c\u0001\u0000\u0000\u0000\u00a8\u009f\u0001"+ + "\u0000\u0000\u0000\u00a8\u00a2\u0001\u0000\u0000\u0000\u00a8\u00a5\u0001"+ + "\u0000\u0000\u0000\u00a9\u00ac\u0001\u0000\u0000\u0000\u00aa\u00a8\u0001"+ + "\u0000\u0000\u0000\u00aa\u00ab\u0001\u0000\u0000\u0000\u00ab\u001d\u0001"+ + "\u0000\u0000\u0000\u00ac\u00aa\u0001\u0000\u0000\u0000\u00ad\u00ae\u0005"+ + "*\u0000\u0000\u00ae\u00af\u0005\f\u0000\u0000\u00af\u00b0\u0003\u001c"+ + "\u000e\u0000\u00b0\u00b1\u0005\r\u0000\u0000\u00b1\u00b5\u0001\u0000\u0000"+ + "\u0000\u00b2\u00b5\u0003$\u0012\u0000\u00b3\u00b5\u0005*\u0000\u0000\u00b4"+ + "\u00ad\u0001\u0000\u0000\u0000\u00b4\u00b2\u0001\u0000\u0000\u0000\u00b4"+ + "\u00b3\u0001\u0000\u0000\u0000\u00b5\u001f\u0001\u0000\u0000\u0000\u00b6"+ + "\u00b7\u0003(\u0014\u0000\u00b7\u00b8\u0003\"\u0011\u0000\u00b8\u00b9"+ + "\u0003\"\u0011\u0000\u00b9!\u0001\u0000\u0000\u0000\u00ba\u00bd\u0005"+ + "(\u0000\u0000\u00bb\u00bd\u0003&\u0013\u0000\u00bc\u00ba\u0001\u0000\u0000"+ + "\u0000\u00bc\u00bb\u0001\u0000\u0000\u0000\u00bd#\u0001\u0000\u0000\u0000"+ + "\u00be\u00c2\u0005(\u0000\u0000\u00bf\u00c2\u0005\'\u0000\u0000\u00c0"+ + "\u00c2\u0003&\u0013\u0000\u00c1\u00be\u0001\u0000\u0000\u0000\u00c1\u00bf"+ + "\u0001\u0000\u0000\u0000\u00c1\u00c0\u0001\u0000\u0000\u0000\u00c2%\u0001"+ + "\u0000\u0000\u0000\u00c3\u00c4\u0005+\u0000\u0000\u00c4\'\u0001\u0000"+ + "\u0000\u0000\u00c5\u00c7\u0007\u0004\u0000\u0000\u00c6\u00c8\u0005 \u0000"+ + "\u0000\u00c7\u00c6\u0001\u0000\u0000\u0000\u00c7\u00c8\u0001\u0000\u0000"+ + "\u0000\u00c8)\u0001\u0000\u0000\u0000\u00c9\u00ca\u0007\u0005\u0000\u0000"+ + "\u00ca+\u0001\u0000\u0000\u0000\u000f/@ENR\\e\u0087\u0097\u00a8\u00aa"+ + "\u00b4\u00bc\u00c1\u00c7"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/HybroLang/HybroLang.interp b/HybroLang/HybroLang.interp new file mode 100644 index 0000000..4f98fb4 --- /dev/null +++ b/HybroLang/HybroLang.interp @@ -0,0 +1,125 @@ +token literal names: +null +'(' +')' +'{' +'}' +',' +';' +'for' +'if' +'else' +'return' +'=' +'[' +']' +'*' +'/' +'+' +'-' +'<<' +'>>' +'&' +'|' +'^' +'int' +'uint' +'sint' +'suint' +'flt' +'cpl' +'pix' +'ipv4' +'ipv6' +'[]' +'==' +'!=' +'<' +'>' +'<=' +'>=' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +DecimalFloatingConstant +IntegerConstant +DecimalConstant +Name +INLINE +WhiteSpace +LineComment +NewLine + +rule names: +compilationunit +function +fndcl +fnprototype +fnbody +paramdcllist +localvardef +vardcllist +vardcl +actionlist +condexpr +action +returnexpr +affectexpr +unaryexpr +varorvalue +datatype +intconstvalue +constvalue +constinline +typebase +condOperator + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 48, 206, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 3, 2, 6, 2, 48, 10, 2, 13, 2, 14, 2, 49, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 7, 6, 65, 10, 6, 12, 6, 14, 6, 68, 11, 6, 3, 6, 3, 6, 5, 6, 72, 10, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 7, 7, 79, 10, 7, 12, 7, 14, 7, 82, 11, 7, 3, 7, 5, 7, 85, 10, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 7, 9, 93, 10, 9, 12, 9, 14, 9, 96, 11, 9, 3, 10, 3, 10, 3, 10, 3, 11, 7, 11, 102, 10, 11, 12, 11, 14, 11, 105, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 138, 10, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 154, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 171, 10, 16, 12, 16, 14, 16, 174, 11, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 183, 10, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 191, 10, 19, 3, 20, 3, 20, 3, 20, 5, 20, 196, 10, 20, 3, 21, 3, 21, 3, 22, 3, 22, 5, 22, 202, 10, 22, 3, 23, 3, 23, 3, 23, 2, 3, 30, 24, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 2, 8, 3, 2, 16, 17, 3, 2, 18, 19, 3, 2, 20, 21, 3, 2, 22, 24, 3, 2, 25, 33, 3, 2, 35, 40, 2, 203, 2, 47, 3, 2, 2, 2, 4, 51, 3, 2, 2, 2, 6, 54, 3, 2, 2, 2, 8, 58, 3, 2, 2, 2, 10, 62, 3, 2, 2, 2, 12, 84, 3, 2, 2, 2, 14, 86, 3, 2, 2, 2, 16, 89, 3, 2, 2, 2, 18, 97, 3, 2, 2, 2, 20, 103, 3, 2, 2, 2, 22, 106, 3, 2, 2, 2, 24, 137, 3, 2, 2, 2, 26, 139, 3, 2, 2, 2, 28, 153, 3, 2, 2, 2, 30, 155, 3, 2, 2, 2, 32, 182, 3, 2, 2, 2, 34, 184, 3, 2, 2, 2, 36, 190, 3, 2, 2, 2, 38, 195, 3, 2, 2, 2, 40, 197, 3, 2, 2, 2, 42, 199, 3, 2, 2, 2, 44, 203, 3, 2, 2, 2, 46, 48, 5, 4, 3, 2, 47, 46, 3, 2, 2, 2, 48, 49, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 49, 50, 3, 2, 2, 2, 50, 3, 3, 2, 2, 2, 51, 52, 5, 6, 4, 2, 52, 53, 5, 10, 6, 2, 53, 5, 3, 2, 2, 2, 54, 55, 5, 34, 18, 2, 55, 56, 7, 44, 2, 2, 56, 57, 5, 8, 5, 2, 57, 7, 3, 2, 2, 2, 58, 59, 7, 3, 2, 2, 59, 60, 5, 12, 7, 2, 60, 61, 7, 4, 2, 2, 61, 9, 3, 2, 2, 2, 62, 66, 7, 5, 2, 2, 63, 65, 5, 14, 8, 2, 64, 63, 3, 2, 2, 2, 65, 68, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 69, 3, 2, 2, 2, 68, 66, 3, 2, 2, 2, 69, 71, 5, 20, 11, 2, 70, 72, 5, 26, 14, 2, 71, 70, 3, 2, 2, 2, 71, 72, 3, 2, 2, 2, 72, 73, 3, 2, 2, 2, 73, 74, 7, 6, 2, 2, 74, 11, 3, 2, 2, 2, 75, 80, 5, 18, 10, 2, 76, 77, 7, 7, 2, 2, 77, 79, 5, 18, 10, 2, 78, 76, 3, 2, 2, 2, 79, 82, 3, 2, 2, 2, 80, 78, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 85, 3, 2, 2, 2, 82, 80, 3, 2, 2, 2, 83, 85, 3, 2, 2, 2, 84, 75, 3, 2, 2, 2, 84, 83, 3, 2, 2, 2, 85, 13, 3, 2, 2, 2, 86, 87, 5, 16, 9, 2, 87, 88, 7, 8, 2, 2, 88, 15, 3, 2, 2, 2, 89, 94, 5, 18, 10, 2, 90, 91, 7, 7, 2, 2, 91, 93, 7, 44, 2, 2, 92, 90, 3, 2, 2, 2, 93, 96, 3, 2, 2, 2, 94, 92, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 17, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 97, 98, 5, 34, 18, 2, 98, 99, 7, 44, 2, 2, 99, 19, 3, 2, 2, 2, 100, 102, 5, 24, 13, 2, 101, 100, 3, 2, 2, 2, 102, 105, 3, 2, 2, 2, 103, 101, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 21, 3, 2, 2, 2, 105, 103, 3, 2, 2, 2, 106, 107, 5, 32, 17, 2, 107, 108, 5, 44, 23, 2, 108, 109, 5, 32, 17, 2, 109, 23, 3, 2, 2, 2, 110, 111, 5, 28, 15, 2, 111, 112, 7, 8, 2, 2, 112, 138, 3, 2, 2, 2, 113, 114, 7, 9, 2, 2, 114, 115, 7, 3, 2, 2, 115, 116, 5, 28, 15, 2, 116, 117, 7, 8, 2, 2, 117, 118, 5, 22, 12, 2, 118, 119, 7, 8, 2, 2, 119, 120, 5, 28, 15, 2, 120, 121, 7, 4, 2, 2, 121, 122, 7, 5, 2, 2, 122, 123, 5, 20, 11, 2, 123, 124, 7, 6, 2, 2, 124, 138, 3, 2, 2, 2, 125, 126, 7, 10, 2, 2, 126, 127, 7, 3, 2, 2, 127, 128, 5, 22, 12, 2, 128, 129, 7, 4, 2, 2, 129, 130, 7, 5, 2, 2, 130, 131, 5, 20, 11, 2, 131, 132, 7, 6, 2, 2, 132, 133, 7, 11, 2, 2, 133, 134, 7, 5, 2, 2, 134, 135, 5, 20, 11, 2, 135, 136, 7, 6, 2, 2, 136, 138, 3, 2, 2, 2, 137, 110, 3, 2, 2, 2, 137, 113, 3, 2, 2, 2, 137, 125, 3, 2, 2, 2, 138, 25, 3, 2, 2, 2, 139, 140, 7, 12, 2, 2, 140, 141, 5, 30, 16, 2, 141, 142, 7, 8, 2, 2, 142, 27, 3, 2, 2, 2, 143, 144, 7, 44, 2, 2, 144, 145, 7, 13, 2, 2, 145, 154, 5, 30, 16, 2, 146, 147, 7, 44, 2, 2, 147, 148, 7, 14, 2, 2, 148, 149, 5, 30, 16, 2, 149, 150, 7, 15, 2, 2, 150, 151, 7, 13, 2, 2, 151, 152, 5, 30, 16, 2, 152, 154, 3, 2, 2, 2, 153, 143, 3, 2, 2, 2, 153, 146, 3, 2, 2, 2, 154, 29, 3, 2, 2, 2, 155, 156, 8, 16, 1, 2, 156, 157, 5, 32, 17, 2, 157, 172, 3, 2, 2, 2, 158, 159, 12, 7, 2, 2, 159, 160, 9, 2, 2, 2, 160, 171, 5, 30, 16, 8, 161, 162, 12, 6, 2, 2, 162, 163, 9, 3, 2, 2, 163, 171, 5, 30, 16, 7, 164, 165, 12, 5, 2, 2, 165, 166, 9, 4, 2, 2, 166, 171, 5, 30, 16, 6, 167, 168, 12, 4, 2, 2, 168, 169, 9, 5, 2, 2, 169, 171, 5, 30, 16, 5, 170, 158, 3, 2, 2, 2, 170, 161, 3, 2, 2, 2, 170, 164, 3, 2, 2, 2, 170, 167, 3, 2, 2, 2, 171, 174, 3, 2, 2, 2, 172, 170, 3, 2, 2, 2, 172, 173, 3, 2, 2, 2, 173, 31, 3, 2, 2, 2, 174, 172, 3, 2, 2, 2, 175, 176, 7, 44, 2, 2, 176, 177, 7, 14, 2, 2, 177, 178, 5, 30, 16, 2, 178, 179, 7, 15, 2, 2, 179, 183, 3, 2, 2, 2, 180, 183, 5, 38, 20, 2, 181, 183, 7, 44, 2, 2, 182, 175, 3, 2, 2, 2, 182, 180, 3, 2, 2, 2, 182, 181, 3, 2, 2, 2, 183, 33, 3, 2, 2, 2, 184, 185, 5, 42, 22, 2, 185, 186, 5, 36, 19, 2, 186, 187, 5, 36, 19, 2, 187, 35, 3, 2, 2, 2, 188, 191, 7, 42, 2, 2, 189, 191, 5, 40, 21, 2, 190, 188, 3, 2, 2, 2, 190, 189, 3, 2, 2, 2, 191, 37, 3, 2, 2, 2, 192, 196, 7, 42, 2, 2, 193, 196, 7, 41, 2, 2, 194, 196, 5, 40, 21, 2, 195, 192, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 195, 194, 3, 2, 2, 2, 196, 39, 3, 2, 2, 2, 197, 198, 7, 45, 2, 2, 198, 41, 3, 2, 2, 2, 199, 201, 9, 6, 2, 2, 200, 202, 7, 34, 2, 2, 201, 200, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 43, 3, 2, 2, 2, 203, 204, 9, 7, 2, 2, 204, 45, 3, 2, 2, 2, 17, 49, 66, 71, 80, 84, 94, 103, 137, 153, 170, 172, 182, 190, 195, 201] \ No newline at end of file diff --git a/HybroLang/HybroLang.tokens b/HybroLang/HybroLang.tokens new file mode 100644 index 0000000..574a34a --- /dev/null +++ b/HybroLang/HybroLang.tokens @@ -0,0 +1,84 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +DecimalFloatingConstant=39 +IntegerConstant=40 +DecimalConstant=41 +Name=42 +INLINE=43 +WhiteSpace=44 +LineComment=45 +NewLine=46 +'('=1 +')'=2 +'{'=3 +'}'=4 +','=5 +';'=6 +'for'=7 +'if'=8 +'else'=9 +'return'=10 +'='=11 +'['=12 +']'=13 +'*'=14 +'/'=15 +'+'=16 +'-'=17 +'<<'=18 +'>>'=19 +'&'=20 +'|'=21 +'^'=22 +'int'=23 +'uint'=24 +'sint'=25 +'suint'=26 +'flt'=27 +'cpl'=28 +'pix'=29 +'ipv4'=30 +'ipv6'=31 +'[]'=32 +'=='=33 +'!='=34 +'<'=35 +'>'=36 +'<='=37 +'>='=38 diff --git a/HybroLang/HybroLangLexer.interp b/HybroLang/HybroLangLexer.interp new file mode 100644 index 0000000..49e7b7c --- /dev/null +++ b/HybroLang/HybroLangLexer.interp @@ -0,0 +1,162 @@ +token literal names: +null +'(' +')' +'{' +'}' +',' +';' +'for' +'if' +'else' +'return' +'=' +'[' +']' +'*' +'/' +'+' +'-' +'<<' +'>>' +'&' +'|' +'^' +'int' +'uint' +'sint' +'suint' +'flt' +'cpl' +'pix' +'ipv4' +'ipv6' +'[]' +'==' +'!=' +'<' +'>' +'<=' +'>=' +null +null +null +null +null +null +null +null + +token symbolic names: +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +DecimalFloatingConstant +IntegerConstant +DecimalConstant +Name +INLINE +WhiteSpace +LineComment +NewLine + +rule names: +T__0 +T__1 +T__2 +T__3 +T__4 +T__5 +T__6 +T__7 +T__8 +T__9 +T__10 +T__11 +T__12 +T__13 +T__14 +T__15 +T__16 +T__17 +T__18 +T__19 +T__20 +T__21 +T__22 +T__23 +T__24 +T__25 +T__26 +T__27 +T__28 +T__29 +T__30 +T__31 +T__32 +T__33 +T__34 +T__35 +T__36 +T__37 +DecimalFloatingConstant +ExponentPart +FloatingSuffix +FractionalConstant +IntegerConstant +DecimalConstant +DigitSequence +Digit +NonzeroDigit +Sign +Name +INLINE +WhiteSpace +LineComment +NewLine + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 48, 322, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 5, 40, 230, 10, 40, 3, 40, 5, 40, 233, 10, 40, 3, 41, 3, 41, 5, 41, 237, 10, 41, 3, 41, 3, 41, 3, 41, 5, 41, 242, 10, 41, 3, 41, 5, 41, 245, 10, 41, 3, 42, 3, 42, 3, 43, 5, 43, 250, 10, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 257, 10, 43, 3, 44, 3, 44, 3, 45, 3, 45, 7, 45, 263, 10, 45, 12, 45, 14, 45, 266, 11, 45, 3, 46, 6, 46, 269, 10, 46, 13, 46, 14, 46, 270, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 7, 50, 281, 10, 50, 12, 50, 14, 50, 284, 11, 50, 3, 51, 3, 51, 3, 51, 3, 51, 6, 51, 290, 10, 51, 13, 51, 14, 51, 291, 3, 51, 3, 51, 3, 52, 6, 52, 297, 10, 52, 13, 52, 14, 52, 298, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 7, 53, 307, 10, 53, 12, 53, 14, 53, 310, 11, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 5, 54, 317, 10, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 308, 2, 55, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 2, 83, 2, 85, 2, 87, 42, 89, 43, 91, 2, 93, 2, 95, 2, 97, 2, 99, 44, 101, 45, 103, 46, 105, 47, 107, 48, 3, 2, 10, 6, 2, 72, 72, 78, 78, 104, 104, 110, 110, 3, 2, 50, 59, 3, 2, 51, 59, 4, 2, 45, 45, 47, 47, 4, 2, 67, 92, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 43, 43, 4, 2, 11, 11, 34, 34, 2, 328, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 3, 109, 3, 2, 2, 2, 5, 111, 3, 2, 2, 2, 7, 113, 3, 2, 2, 2, 9, 115, 3, 2, 2, 2, 11, 117, 3, 2, 2, 2, 13, 119, 3, 2, 2, 2, 15, 121, 3, 2, 2, 2, 17, 125, 3, 2, 2, 2, 19, 128, 3, 2, 2, 2, 21, 133, 3, 2, 2, 2, 23, 140, 3, 2, 2, 2, 25, 142, 3, 2, 2, 2, 27, 144, 3, 2, 2, 2, 29, 146, 3, 2, 2, 2, 31, 148, 3, 2, 2, 2, 33, 150, 3, 2, 2, 2, 35, 152, 3, 2, 2, 2, 37, 154, 3, 2, 2, 2, 39, 157, 3, 2, 2, 2, 41, 160, 3, 2, 2, 2, 43, 162, 3, 2, 2, 2, 45, 164, 3, 2, 2, 2, 47, 166, 3, 2, 2, 2, 49, 170, 3, 2, 2, 2, 51, 175, 3, 2, 2, 2, 53, 180, 3, 2, 2, 2, 55, 186, 3, 2, 2, 2, 57, 190, 3, 2, 2, 2, 59, 194, 3, 2, 2, 2, 61, 198, 3, 2, 2, 2, 63, 203, 3, 2, 2, 2, 65, 208, 3, 2, 2, 2, 67, 211, 3, 2, 2, 2, 69, 214, 3, 2, 2, 2, 71, 217, 3, 2, 2, 2, 73, 219, 3, 2, 2, 2, 75, 221, 3, 2, 2, 2, 77, 224, 3, 2, 2, 2, 79, 227, 3, 2, 2, 2, 81, 244, 3, 2, 2, 2, 83, 246, 3, 2, 2, 2, 85, 256, 3, 2, 2, 2, 87, 258, 3, 2, 2, 2, 89, 260, 3, 2, 2, 2, 91, 268, 3, 2, 2, 2, 93, 272, 3, 2, 2, 2, 95, 274, 3, 2, 2, 2, 97, 276, 3, 2, 2, 2, 99, 278, 3, 2, 2, 2, 101, 285, 3, 2, 2, 2, 103, 296, 3, 2, 2, 2, 105, 302, 3, 2, 2, 2, 107, 316, 3, 2, 2, 2, 109, 110, 7, 42, 2, 2, 110, 4, 3, 2, 2, 2, 111, 112, 7, 43, 2, 2, 112, 6, 3, 2, 2, 2, 113, 114, 7, 125, 2, 2, 114, 8, 3, 2, 2, 2, 115, 116, 7, 127, 2, 2, 116, 10, 3, 2, 2, 2, 117, 118, 7, 46, 2, 2, 118, 12, 3, 2, 2, 2, 119, 120, 7, 61, 2, 2, 120, 14, 3, 2, 2, 2, 121, 122, 7, 104, 2, 2, 122, 123, 7, 113, 2, 2, 123, 124, 7, 116, 2, 2, 124, 16, 3, 2, 2, 2, 125, 126, 7, 107, 2, 2, 126, 127, 7, 104, 2, 2, 127, 18, 3, 2, 2, 2, 128, 129, 7, 103, 2, 2, 129, 130, 7, 110, 2, 2, 130, 131, 7, 117, 2, 2, 131, 132, 7, 103, 2, 2, 132, 20, 3, 2, 2, 2, 133, 134, 7, 116, 2, 2, 134, 135, 7, 103, 2, 2, 135, 136, 7, 118, 2, 2, 136, 137, 7, 119, 2, 2, 137, 138, 7, 116, 2, 2, 138, 139, 7, 112, 2, 2, 139, 22, 3, 2, 2, 2, 140, 141, 7, 63, 2, 2, 141, 24, 3, 2, 2, 2, 142, 143, 7, 93, 2, 2, 143, 26, 3, 2, 2, 2, 144, 145, 7, 95, 2, 2, 145, 28, 3, 2, 2, 2, 146, 147, 7, 44, 2, 2, 147, 30, 3, 2, 2, 2, 148, 149, 7, 49, 2, 2, 149, 32, 3, 2, 2, 2, 150, 151, 7, 45, 2, 2, 151, 34, 3, 2, 2, 2, 152, 153, 7, 47, 2, 2, 153, 36, 3, 2, 2, 2, 154, 155, 7, 62, 2, 2, 155, 156, 7, 62, 2, 2, 156, 38, 3, 2, 2, 2, 157, 158, 7, 64, 2, 2, 158, 159, 7, 64, 2, 2, 159, 40, 3, 2, 2, 2, 160, 161, 7, 40, 2, 2, 161, 42, 3, 2, 2, 2, 162, 163, 7, 126, 2, 2, 163, 44, 3, 2, 2, 2, 164, 165, 7, 96, 2, 2, 165, 46, 3, 2, 2, 2, 166, 167, 7, 107, 2, 2, 167, 168, 7, 112, 2, 2, 168, 169, 7, 118, 2, 2, 169, 48, 3, 2, 2, 2, 170, 171, 7, 119, 2, 2, 171, 172, 7, 107, 2, 2, 172, 173, 7, 112, 2, 2, 173, 174, 7, 118, 2, 2, 174, 50, 3, 2, 2, 2, 175, 176, 7, 117, 2, 2, 176, 177, 7, 107, 2, 2, 177, 178, 7, 112, 2, 2, 178, 179, 7, 118, 2, 2, 179, 52, 3, 2, 2, 2, 180, 181, 7, 117, 2, 2, 181, 182, 7, 119, 2, 2, 182, 183, 7, 107, 2, 2, 183, 184, 7, 112, 2, 2, 184, 185, 7, 118, 2, 2, 185, 54, 3, 2, 2, 2, 186, 187, 7, 104, 2, 2, 187, 188, 7, 110, 2, 2, 188, 189, 7, 118, 2, 2, 189, 56, 3, 2, 2, 2, 190, 191, 7, 101, 2, 2, 191, 192, 7, 114, 2, 2, 192, 193, 7, 110, 2, 2, 193, 58, 3, 2, 2, 2, 194, 195, 7, 114, 2, 2, 195, 196, 7, 107, 2, 2, 196, 197, 7, 122, 2, 2, 197, 60, 3, 2, 2, 2, 198, 199, 7, 107, 2, 2, 199, 200, 7, 114, 2, 2, 200, 201, 7, 120, 2, 2, 201, 202, 7, 54, 2, 2, 202, 62, 3, 2, 2, 2, 203, 204, 7, 107, 2, 2, 204, 205, 7, 114, 2, 2, 205, 206, 7, 120, 2, 2, 206, 207, 7, 56, 2, 2, 207, 64, 3, 2, 2, 2, 208, 209, 7, 93, 2, 2, 209, 210, 7, 95, 2, 2, 210, 66, 3, 2, 2, 2, 211, 212, 7, 63, 2, 2, 212, 213, 7, 63, 2, 2, 213, 68, 3, 2, 2, 2, 214, 215, 7, 35, 2, 2, 215, 216, 7, 63, 2, 2, 216, 70, 3, 2, 2, 2, 217, 218, 7, 62, 2, 2, 218, 72, 3, 2, 2, 2, 219, 220, 7, 64, 2, 2, 220, 74, 3, 2, 2, 2, 221, 222, 7, 62, 2, 2, 222, 223, 7, 63, 2, 2, 223, 76, 3, 2, 2, 2, 224, 225, 7, 64, 2, 2, 225, 226, 7, 63, 2, 2, 226, 78, 3, 2, 2, 2, 227, 229, 5, 85, 43, 2, 228, 230, 5, 81, 41, 2, 229, 228, 3, 2, 2, 2, 229, 230, 3, 2, 2, 2, 230, 232, 3, 2, 2, 2, 231, 233, 5, 83, 42, 2, 232, 231, 3, 2, 2, 2, 232, 233, 3, 2, 2, 2, 233, 80, 3, 2, 2, 2, 234, 236, 7, 103, 2, 2, 235, 237, 5, 97, 49, 2, 236, 235, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 238, 3, 2, 2, 2, 238, 245, 5, 91, 46, 2, 239, 241, 7, 71, 2, 2, 240, 242, 5, 97, 49, 2, 241, 240, 3, 2, 2, 2, 241, 242, 3, 2, 2, 2, 242, 243, 3, 2, 2, 2, 243, 245, 5, 91, 46, 2, 244, 234, 3, 2, 2, 2, 244, 239, 3, 2, 2, 2, 245, 82, 3, 2, 2, 2, 246, 247, 9, 2, 2, 2, 247, 84, 3, 2, 2, 2, 248, 250, 5, 91, 46, 2, 249, 248, 3, 2, 2, 2, 249, 250, 3, 2, 2, 2, 250, 251, 3, 2, 2, 2, 251, 252, 7, 48, 2, 2, 252, 257, 5, 91, 46, 2, 253, 254, 5, 91, 46, 2, 254, 255, 7, 48, 2, 2, 255, 257, 3, 2, 2, 2, 256, 249, 3, 2, 2, 2, 256, 253, 3, 2, 2, 2, 257, 86, 3, 2, 2, 2, 258, 259, 5, 91, 46, 2, 259, 88, 3, 2, 2, 2, 260, 264, 5, 95, 48, 2, 261, 263, 5, 93, 47, 2, 262, 261, 3, 2, 2, 2, 263, 266, 3, 2, 2, 2, 264, 262, 3, 2, 2, 2, 264, 265, 3, 2, 2, 2, 265, 90, 3, 2, 2, 2, 266, 264, 3, 2, 2, 2, 267, 269, 5, 93, 47, 2, 268, 267, 3, 2, 2, 2, 269, 270, 3, 2, 2, 2, 270, 268, 3, 2, 2, 2, 270, 271, 3, 2, 2, 2, 271, 92, 3, 2, 2, 2, 272, 273, 9, 3, 2, 2, 273, 94, 3, 2, 2, 2, 274, 275, 9, 4, 2, 2, 275, 96, 3, 2, 2, 2, 276, 277, 9, 5, 2, 2, 277, 98, 3, 2, 2, 2, 278, 282, 9, 6, 2, 2, 279, 281, 9, 7, 2, 2, 280, 279, 3, 2, 2, 2, 281, 284, 3, 2, 2, 2, 282, 280, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, 100, 3, 2, 2, 2, 284, 282, 3, 2, 2, 2, 285, 286, 7, 37, 2, 2, 286, 287, 7, 42, 2, 2, 287, 289, 3, 2, 2, 2, 288, 290, 10, 8, 2, 2, 289, 288, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 289, 3, 2, 2, 2, 291, 292, 3, 2, 2, 2, 292, 293, 3, 2, 2, 2, 293, 294, 7, 43, 2, 2, 294, 102, 3, 2, 2, 2, 295, 297, 9, 9, 2, 2, 296, 295, 3, 2, 2, 2, 297, 298, 3, 2, 2, 2, 298, 296, 3, 2, 2, 2, 298, 299, 3, 2, 2, 2, 299, 300, 3, 2, 2, 2, 300, 301, 8, 52, 2, 2, 301, 104, 3, 2, 2, 2, 302, 303, 7, 49, 2, 2, 303, 304, 7, 49, 2, 2, 304, 308, 3, 2, 2, 2, 305, 307, 11, 2, 2, 2, 306, 305, 3, 2, 2, 2, 307, 310, 3, 2, 2, 2, 308, 309, 3, 2, 2, 2, 308, 306, 3, 2, 2, 2, 309, 311, 3, 2, 2, 2, 310, 308, 3, 2, 2, 2, 311, 312, 5, 107, 54, 2, 312, 313, 3, 2, 2, 2, 313, 314, 8, 53, 2, 2, 314, 106, 3, 2, 2, 2, 315, 317, 7, 15, 2, 2, 316, 315, 3, 2, 2, 2, 316, 317, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 319, 7, 12, 2, 2, 319, 320, 3, 2, 2, 2, 320, 321, 8, 54, 2, 2, 321, 108, 3, 2, 2, 2, 17, 2, 229, 232, 236, 241, 244, 249, 256, 264, 270, 282, 291, 298, 308, 316, 3, 8, 2, 2] \ No newline at end of file diff --git a/HybroLang/HybroLangLexer.py b/HybroLang/HybroLangLexer.py new file mode 100644 index 0000000..e628c3e --- /dev/null +++ b/HybroLang/HybroLangLexer.py @@ -0,0 +1,240 @@ +# Generated from HybroLang.g4 by ANTLR 4.9.2 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + + +def serializedATN(): + with StringIO() as buf: + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\60") + buf.write("\u0142\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7") + buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r") + buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23") + buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30") + buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36") + buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%") + buf.write("\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.") + buf.write("\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64") + buf.write("\t\64\4\65\t\65\4\66\t\66\3\2\3\2\3\3\3\3\3\4\3\4\3\5") + buf.write("\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\n\3") + buf.write("\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f") + buf.write("\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3") + buf.write("\22\3\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26") + buf.write("\3\26\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31") + buf.write("\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33") + buf.write("\3\33\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36") + buf.write("\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3!") + buf.write("\3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3%\3%\3&\3&\3&\3\'\3") + buf.write("\'\3\'\3(\3(\5(\u00e6\n(\3(\5(\u00e9\n(\3)\3)\5)\u00ed") + buf.write("\n)\3)\3)\3)\5)\u00f2\n)\3)\5)\u00f5\n)\3*\3*\3+\5+\u00fa") + buf.write("\n+\3+\3+\3+\3+\3+\5+\u0101\n+\3,\3,\3-\3-\7-\u0107\n") + buf.write("-\f-\16-\u010a\13-\3.\6.\u010d\n.\r.\16.\u010e\3/\3/\3") + buf.write("\60\3\60\3\61\3\61\3\62\3\62\7\62\u0119\n\62\f\62\16\62") + buf.write("\u011c\13\62\3\63\3\63\3\63\3\63\6\63\u0122\n\63\r\63") + buf.write("\16\63\u0123\3\63\3\63\3\64\6\64\u0129\n\64\r\64\16\64") + buf.write("\u012a\3\64\3\64\3\65\3\65\3\65\3\65\7\65\u0133\n\65\f") + buf.write("\65\16\65\u0136\13\65\3\65\3\65\3\65\3\65\3\66\5\66\u013d") + buf.write("\n\66\3\66\3\66\3\66\3\66\3\u0134\2\67\3\3\5\4\7\5\t\6") + buf.write("\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20") + buf.write("\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65") + buf.write("\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q\2S\2U\2W*Y+[") + buf.write("\2]\2_\2a\2c,e-g.i/k\60\3\2\n\6\2HHNNhhnn\3\2\62;\3\2") + buf.write("\63;\4\2--//\4\2C\\c|\6\2\62;C\\aac|\3\2++\4\2\13\13\"") + buf.write("\"\2\u0148\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2") + buf.write("\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2") + buf.write("\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2") + buf.write("\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#") + buf.write("\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2") + buf.write("\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65") + buf.write("\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2") + buf.write("\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2") + buf.write("\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2W\3\2") + buf.write("\2\2\2Y\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3") + buf.write("\2\2\2\2k\3\2\2\2\3m\3\2\2\2\5o\3\2\2\2\7q\3\2\2\2\ts") + buf.write("\3\2\2\2\13u\3\2\2\2\rw\3\2\2\2\17y\3\2\2\2\21}\3\2\2") + buf.write("\2\23\u0080\3\2\2\2\25\u0085\3\2\2\2\27\u008c\3\2\2\2") + buf.write("\31\u008e\3\2\2\2\33\u0090\3\2\2\2\35\u0092\3\2\2\2\37") + buf.write("\u0094\3\2\2\2!\u0096\3\2\2\2#\u0098\3\2\2\2%\u009a\3") + buf.write("\2\2\2\'\u009d\3\2\2\2)\u00a0\3\2\2\2+\u00a2\3\2\2\2-") + buf.write("\u00a4\3\2\2\2/\u00a6\3\2\2\2\61\u00aa\3\2\2\2\63\u00af") + buf.write("\3\2\2\2\65\u00b4\3\2\2\2\67\u00ba\3\2\2\29\u00be\3\2") + buf.write("\2\2;\u00c2\3\2\2\2=\u00c6\3\2\2\2?\u00cb\3\2\2\2A\u00d0") + buf.write("\3\2\2\2C\u00d3\3\2\2\2E\u00d6\3\2\2\2G\u00d9\3\2\2\2") + buf.write("I\u00db\3\2\2\2K\u00dd\3\2\2\2M\u00e0\3\2\2\2O\u00e3\3") + buf.write("\2\2\2Q\u00f4\3\2\2\2S\u00f6\3\2\2\2U\u0100\3\2\2\2W\u0102") + buf.write("\3\2\2\2Y\u0104\3\2\2\2[\u010c\3\2\2\2]\u0110\3\2\2\2") + buf.write("_\u0112\3\2\2\2a\u0114\3\2\2\2c\u0116\3\2\2\2e\u011d\3") + buf.write("\2\2\2g\u0128\3\2\2\2i\u012e\3\2\2\2k\u013c\3\2\2\2mn") + buf.write("\7*\2\2n\4\3\2\2\2op\7+\2\2p\6\3\2\2\2qr\7}\2\2r\b\3\2") + buf.write("\2\2st\7\177\2\2t\n\3\2\2\2uv\7.\2\2v\f\3\2\2\2wx\7=\2") + buf.write("\2x\16\3\2\2\2yz\7h\2\2z{\7q\2\2{|\7t\2\2|\20\3\2\2\2") + buf.write("}~\7k\2\2~\177\7h\2\2\177\22\3\2\2\2\u0080\u0081\7g\2") + buf.write("\2\u0081\u0082\7n\2\2\u0082\u0083\7u\2\2\u0083\u0084\7") + buf.write("g\2\2\u0084\24\3\2\2\2\u0085\u0086\7t\2\2\u0086\u0087") + buf.write("\7g\2\2\u0087\u0088\7v\2\2\u0088\u0089\7w\2\2\u0089\u008a") + buf.write("\7t\2\2\u008a\u008b\7p\2\2\u008b\26\3\2\2\2\u008c\u008d") + buf.write("\7?\2\2\u008d\30\3\2\2\2\u008e\u008f\7]\2\2\u008f\32\3") + buf.write("\2\2\2\u0090\u0091\7_\2\2\u0091\34\3\2\2\2\u0092\u0093") + buf.write("\7,\2\2\u0093\36\3\2\2\2\u0094\u0095\7\61\2\2\u0095 \3") + buf.write("\2\2\2\u0096\u0097\7-\2\2\u0097\"\3\2\2\2\u0098\u0099") + buf.write("\7/\2\2\u0099$\3\2\2\2\u009a\u009b\7>\2\2\u009b\u009c") + buf.write("\7>\2\2\u009c&\3\2\2\2\u009d\u009e\7@\2\2\u009e\u009f") + buf.write("\7@\2\2\u009f(\3\2\2\2\u00a0\u00a1\7(\2\2\u00a1*\3\2\2") + buf.write("\2\u00a2\u00a3\7~\2\2\u00a3,\3\2\2\2\u00a4\u00a5\7`\2") + buf.write("\2\u00a5.\3\2\2\2\u00a6\u00a7\7k\2\2\u00a7\u00a8\7p\2") + buf.write("\2\u00a8\u00a9\7v\2\2\u00a9\60\3\2\2\2\u00aa\u00ab\7w") + buf.write("\2\2\u00ab\u00ac\7k\2\2\u00ac\u00ad\7p\2\2\u00ad\u00ae") + buf.write("\7v\2\2\u00ae\62\3\2\2\2\u00af\u00b0\7u\2\2\u00b0\u00b1") + buf.write("\7k\2\2\u00b1\u00b2\7p\2\2\u00b2\u00b3\7v\2\2\u00b3\64") + buf.write("\3\2\2\2\u00b4\u00b5\7u\2\2\u00b5\u00b6\7w\2\2\u00b6\u00b7") + buf.write("\7k\2\2\u00b7\u00b8\7p\2\2\u00b8\u00b9\7v\2\2\u00b9\66") + buf.write("\3\2\2\2\u00ba\u00bb\7h\2\2\u00bb\u00bc\7n\2\2\u00bc\u00bd") + buf.write("\7v\2\2\u00bd8\3\2\2\2\u00be\u00bf\7e\2\2\u00bf\u00c0") + buf.write("\7r\2\2\u00c0\u00c1\7n\2\2\u00c1:\3\2\2\2\u00c2\u00c3") + buf.write("\7r\2\2\u00c3\u00c4\7k\2\2\u00c4\u00c5\7z\2\2\u00c5<\3") + buf.write("\2\2\2\u00c6\u00c7\7k\2\2\u00c7\u00c8\7r\2\2\u00c8\u00c9") + buf.write("\7x\2\2\u00c9\u00ca\7\66\2\2\u00ca>\3\2\2\2\u00cb\u00cc") + buf.write("\7k\2\2\u00cc\u00cd\7r\2\2\u00cd\u00ce\7x\2\2\u00ce\u00cf") + buf.write("\78\2\2\u00cf@\3\2\2\2\u00d0\u00d1\7]\2\2\u00d1\u00d2") + buf.write("\7_\2\2\u00d2B\3\2\2\2\u00d3\u00d4\7?\2\2\u00d4\u00d5") + buf.write("\7?\2\2\u00d5D\3\2\2\2\u00d6\u00d7\7#\2\2\u00d7\u00d8") + buf.write("\7?\2\2\u00d8F\3\2\2\2\u00d9\u00da\7>\2\2\u00daH\3\2\2") + buf.write("\2\u00db\u00dc\7@\2\2\u00dcJ\3\2\2\2\u00dd\u00de\7>\2") + buf.write("\2\u00de\u00df\7?\2\2\u00dfL\3\2\2\2\u00e0\u00e1\7@\2") + buf.write("\2\u00e1\u00e2\7?\2\2\u00e2N\3\2\2\2\u00e3\u00e5\5U+\2") + buf.write("\u00e4\u00e6\5Q)\2\u00e5\u00e4\3\2\2\2\u00e5\u00e6\3\2") + buf.write("\2\2\u00e6\u00e8\3\2\2\2\u00e7\u00e9\5S*\2\u00e8\u00e7") + buf.write("\3\2\2\2\u00e8\u00e9\3\2\2\2\u00e9P\3\2\2\2\u00ea\u00ec") + buf.write("\7g\2\2\u00eb\u00ed\5a\61\2\u00ec\u00eb\3\2\2\2\u00ec") + buf.write("\u00ed\3\2\2\2\u00ed\u00ee\3\2\2\2\u00ee\u00f5\5[.\2\u00ef") + buf.write("\u00f1\7G\2\2\u00f0\u00f2\5a\61\2\u00f1\u00f0\3\2\2\2") + buf.write("\u00f1\u00f2\3\2\2\2\u00f2\u00f3\3\2\2\2\u00f3\u00f5\5") + buf.write("[.\2\u00f4\u00ea\3\2\2\2\u00f4\u00ef\3\2\2\2\u00f5R\3") + buf.write("\2\2\2\u00f6\u00f7\t\2\2\2\u00f7T\3\2\2\2\u00f8\u00fa") + buf.write("\5[.\2\u00f9\u00f8\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fb") + buf.write("\3\2\2\2\u00fb\u00fc\7\60\2\2\u00fc\u0101\5[.\2\u00fd") + buf.write("\u00fe\5[.\2\u00fe\u00ff\7\60\2\2\u00ff\u0101\3\2\2\2") + buf.write("\u0100\u00f9\3\2\2\2\u0100\u00fd\3\2\2\2\u0101V\3\2\2") + buf.write("\2\u0102\u0103\5[.\2\u0103X\3\2\2\2\u0104\u0108\5_\60") + buf.write("\2\u0105\u0107\5]/\2\u0106\u0105\3\2\2\2\u0107\u010a\3") + buf.write("\2\2\2\u0108\u0106\3\2\2\2\u0108\u0109\3\2\2\2\u0109Z") + buf.write("\3\2\2\2\u010a\u0108\3\2\2\2\u010b\u010d\5]/\2\u010c\u010b") + buf.write("\3\2\2\2\u010d\u010e\3\2\2\2\u010e\u010c\3\2\2\2\u010e") + buf.write("\u010f\3\2\2\2\u010f\\\3\2\2\2\u0110\u0111\t\3\2\2\u0111") + buf.write("^\3\2\2\2\u0112\u0113\t\4\2\2\u0113`\3\2\2\2\u0114\u0115") + buf.write("\t\5\2\2\u0115b\3\2\2\2\u0116\u011a\t\6\2\2\u0117\u0119") + buf.write("\t\7\2\2\u0118\u0117\3\2\2\2\u0119\u011c\3\2\2\2\u011a") + buf.write("\u0118\3\2\2\2\u011a\u011b\3\2\2\2\u011bd\3\2\2\2\u011c") + buf.write("\u011a\3\2\2\2\u011d\u011e\7%\2\2\u011e\u011f\7*\2\2\u011f") + buf.write("\u0121\3\2\2\2\u0120\u0122\n\b\2\2\u0121\u0120\3\2\2\2") + buf.write("\u0122\u0123\3\2\2\2\u0123\u0121\3\2\2\2\u0123\u0124\3") + buf.write("\2\2\2\u0124\u0125\3\2\2\2\u0125\u0126\7+\2\2\u0126f\3") + buf.write("\2\2\2\u0127\u0129\t\t\2\2\u0128\u0127\3\2\2\2\u0129\u012a") + buf.write("\3\2\2\2\u012a\u0128\3\2\2\2\u012a\u012b\3\2\2\2\u012b") + buf.write("\u012c\3\2\2\2\u012c\u012d\b\64\2\2\u012dh\3\2\2\2\u012e") + buf.write("\u012f\7\61\2\2\u012f\u0130\7\61\2\2\u0130\u0134\3\2\2") + buf.write("\2\u0131\u0133\13\2\2\2\u0132\u0131\3\2\2\2\u0133\u0136") + buf.write("\3\2\2\2\u0134\u0135\3\2\2\2\u0134\u0132\3\2\2\2\u0135") + buf.write("\u0137\3\2\2\2\u0136\u0134\3\2\2\2\u0137\u0138\5k\66\2") + buf.write("\u0138\u0139\3\2\2\2\u0139\u013a\b\65\2\2\u013aj\3\2\2") + buf.write("\2\u013b\u013d\7\17\2\2\u013c\u013b\3\2\2\2\u013c\u013d") + buf.write("\3\2\2\2\u013d\u013e\3\2\2\2\u013e\u013f\7\f\2\2\u013f") + buf.write("\u0140\3\2\2\2\u0140\u0141\b\66\2\2\u0141l\3\2\2\2\21") + buf.write("\2\u00e5\u00e8\u00ec\u00f1\u00f4\u00f9\u0100\u0108\u010e") + buf.write("\u011a\u0123\u012a\u0134\u013c\3\b\2\2") + return buf.getvalue() + + +class HybroLangLexer(Lexer): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + T__0 = 1 + T__1 = 2 + T__2 = 3 + T__3 = 4 + T__4 = 5 + T__5 = 6 + T__6 = 7 + T__7 = 8 + T__8 = 9 + T__9 = 10 + T__10 = 11 + T__11 = 12 + T__12 = 13 + T__13 = 14 + T__14 = 15 + T__15 = 16 + T__16 = 17 + T__17 = 18 + T__18 = 19 + T__19 = 20 + T__20 = 21 + T__21 = 22 + T__22 = 23 + T__23 = 24 + T__24 = 25 + T__25 = 26 + T__26 = 27 + T__27 = 28 + T__28 = 29 + T__29 = 30 + T__30 = 31 + T__31 = 32 + T__32 = 33 + T__33 = 34 + T__34 = 35 + T__35 = 36 + T__36 = 37 + T__37 = 38 + DecimalFloatingConstant = 39 + IntegerConstant = 40 + DecimalConstant = 41 + Name = 42 + INLINE = 43 + WhiteSpace = 44 + LineComment = 45 + NewLine = 46 + + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + + modeNames = [ "DEFAULT_MODE" ] + + literalNames = [ "", + "'('", "')'", "'{'", "'}'", "','", "';'", "'for'", "'if'", "'else'", + "'return'", "'='", "'['", "']'", "'*'", "'/'", "'+'", "'-'", + "'<<'", "'>>'", "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", + "'suint'", "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", + "'=='", "'!='", "'<'", "'>'", "'<='", "'>='" ] + + symbolicNames = [ "", + "DecimalFloatingConstant", "IntegerConstant", "DecimalConstant", + "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" ] + + ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", + "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13", + "T__14", "T__15", "T__16", "T__17", "T__18", "T__19", + "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", + "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", + "T__32", "T__33", "T__34", "T__35", "T__36", "T__37", + "DecimalFloatingConstant", "ExponentPart", "FloatingSuffix", + "FractionalConstant", "IntegerConstant", "DecimalConstant", + "DigitSequence", "Digit", "NonzeroDigit", "Sign", "Name", + "INLINE", "WhiteSpace", "LineComment", "NewLine" ] + + grammarFileName = "HybroLang.g4" + + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.9.2") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + diff --git a/HybroLang/HybroLangLexer.tokens b/HybroLang/HybroLangLexer.tokens new file mode 100644 index 0000000..574a34a --- /dev/null +++ b/HybroLang/HybroLangLexer.tokens @@ -0,0 +1,84 @@ +T__0=1 +T__1=2 +T__2=3 +T__3=4 +T__4=5 +T__5=6 +T__6=7 +T__7=8 +T__8=9 +T__9=10 +T__10=11 +T__11=12 +T__12=13 +T__13=14 +T__14=15 +T__15=16 +T__16=17 +T__17=18 +T__18=19 +T__19=20 +T__20=21 +T__21=22 +T__22=23 +T__23=24 +T__24=25 +T__25=26 +T__26=27 +T__27=28 +T__28=29 +T__29=30 +T__30=31 +T__31=32 +T__32=33 +T__33=34 +T__34=35 +T__35=36 +T__36=37 +T__37=38 +DecimalFloatingConstant=39 +IntegerConstant=40 +DecimalConstant=41 +Name=42 +INLINE=43 +WhiteSpace=44 +LineComment=45 +NewLine=46 +'('=1 +')'=2 +'{'=3 +'}'=4 +','=5 +';'=6 +'for'=7 +'if'=8 +'else'=9 +'return'=10 +'='=11 +'['=12 +']'=13 +'*'=14 +'/'=15 +'+'=16 +'-'=17 +'<<'=18 +'>>'=19 +'&'=20 +'|'=21 +'^'=22 +'int'=23 +'uint'=24 +'sint'=25 +'suint'=26 +'flt'=27 +'cpl'=28 +'pix'=29 +'ipv4'=30 +'ipv6'=31 +'[]'=32 +'=='=33 +'!='=34 +'<'=35 +'>'=36 +'<='=37 +'>='=38 diff --git a/HybroLang/HybroLangParser.py b/HybroLang/HybroLangParser.py new file mode 100644 index 0000000..9a40ce4 --- /dev/null +++ b/HybroLang/HybroLangParser.py @@ -0,0 +1,1602 @@ +# Generated from HybroLang.g4 by ANTLR 4.9.2 +# encoding: utf-8 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + +def serializedATN(): + with StringIO() as buf: + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\60") + buf.write("\u00ce\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") + buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") + buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") + buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\3\2\6\2\60\n") + buf.write("\2\r\2\16\2\61\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5") + buf.write("\3\5\3\6\3\6\7\6A\n\6\f\6\16\6D\13\6\3\6\3\6\5\6H\n\6") + buf.write("\3\6\3\6\3\7\3\7\3\7\7\7O\n\7\f\7\16\7R\13\7\3\7\5\7U") + buf.write("\n\7\3\b\3\b\3\b\3\t\3\t\3\t\7\t]\n\t\f\t\16\t`\13\t\3") + buf.write("\n\3\n\3\n\3\13\7\13f\n\13\f\13\16\13i\13\13\3\f\3\f\3") + buf.write("\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r") + buf.write("\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3") + buf.write("\r\3\r\5\r\u008a\n\r\3\16\3\16\3\16\3\16\3\17\3\17\3\17") + buf.write("\3\17\3\17\3\17\3\17\3\17\3\17\3\17\5\17\u009a\n\17\3") + buf.write("\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20") + buf.write("\3\20\3\20\3\20\3\20\7\20\u00ab\n\20\f\20\16\20\u00ae") + buf.write("\13\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\5\21\u00b7\n") + buf.write("\21\3\22\3\22\3\22\3\22\3\23\3\23\5\23\u00bf\n\23\3\24") + buf.write("\3\24\3\24\5\24\u00c4\n\24\3\25\3\25\3\26\3\26\5\26\u00ca") + buf.write("\n\26\3\27\3\27\3\27\2\3\36\30\2\4\6\b\n\f\16\20\22\24") + buf.write("\26\30\32\34\36 \"$&(*,\2\b\3\2\20\21\3\2\22\23\3\2\24") + buf.write("\25\3\2\26\30\3\2\31!\3\2#(\2\u00cb\2/\3\2\2\2\4\63\3") + buf.write("\2\2\2\6\66\3\2\2\2\b:\3\2\2\2\n>\3\2\2\2\fT\3\2\2\2\16") + buf.write("V\3\2\2\2\20Y\3\2\2\2\22a\3\2\2\2\24g\3\2\2\2\26j\3\2") + buf.write("\2\2\30\u0089\3\2\2\2\32\u008b\3\2\2\2\34\u0099\3\2\2") + buf.write("\2\36\u009b\3\2\2\2 \u00b6\3\2\2\2\"\u00b8\3\2\2\2$\u00be") + buf.write("\3\2\2\2&\u00c3\3\2\2\2(\u00c5\3\2\2\2*\u00c7\3\2\2\2") + buf.write(",\u00cb\3\2\2\2.\60\5\4\3\2/.\3\2\2\2\60\61\3\2\2\2\61") + buf.write("/\3\2\2\2\61\62\3\2\2\2\62\3\3\2\2\2\63\64\5\6\4\2\64") + buf.write("\65\5\n\6\2\65\5\3\2\2\2\66\67\5\"\22\2\678\7,\2\289\5") + buf.write("\b\5\29\7\3\2\2\2:;\7\3\2\2;<\5\f\7\2<=\7\4\2\2=\t\3\2") + buf.write("\2\2>B\7\5\2\2?A\5\16\b\2@?\3\2\2\2AD\3\2\2\2B@\3\2\2") + buf.write("\2BC\3\2\2\2CE\3\2\2\2DB\3\2\2\2EG\5\24\13\2FH\5\32\16") + buf.write("\2GF\3\2\2\2GH\3\2\2\2HI\3\2\2\2IJ\7\6\2\2J\13\3\2\2\2") + buf.write("KP\5\22\n\2LM\7\7\2\2MO\5\22\n\2NL\3\2\2\2OR\3\2\2\2P") + buf.write("N\3\2\2\2PQ\3\2\2\2QU\3\2\2\2RP\3\2\2\2SU\3\2\2\2TK\3") + buf.write("\2\2\2TS\3\2\2\2U\r\3\2\2\2VW\5\20\t\2WX\7\b\2\2X\17\3") + buf.write("\2\2\2Y^\5\22\n\2Z[\7\7\2\2[]\7,\2\2\\Z\3\2\2\2]`\3\2") + buf.write("\2\2^\\\3\2\2\2^_\3\2\2\2_\21\3\2\2\2`^\3\2\2\2ab\5\"") + buf.write("\22\2bc\7,\2\2c\23\3\2\2\2df\5\30\r\2ed\3\2\2\2fi\3\2") + buf.write("\2\2ge\3\2\2\2gh\3\2\2\2h\25\3\2\2\2ig\3\2\2\2jk\5 \21") + buf.write("\2kl\5,\27\2lm\5 \21\2m\27\3\2\2\2no\5\34\17\2op\7\b\2") + buf.write("\2p\u008a\3\2\2\2qr\7\t\2\2rs\7\3\2\2st\5\34\17\2tu\7") + buf.write("\b\2\2uv\5\26\f\2vw\7\b\2\2wx\5\34\17\2xy\7\4\2\2yz\7") + buf.write("\5\2\2z{\5\24\13\2{|\7\6\2\2|\u008a\3\2\2\2}~\7\n\2\2") + buf.write("~\177\7\3\2\2\177\u0080\5\26\f\2\u0080\u0081\7\4\2\2\u0081") + buf.write("\u0082\7\5\2\2\u0082\u0083\5\24\13\2\u0083\u0084\7\6\2") + buf.write("\2\u0084\u0085\7\13\2\2\u0085\u0086\7\5\2\2\u0086\u0087") + buf.write("\5\24\13\2\u0087\u0088\7\6\2\2\u0088\u008a\3\2\2\2\u0089") + buf.write("n\3\2\2\2\u0089q\3\2\2\2\u0089}\3\2\2\2\u008a\31\3\2\2") + buf.write("\2\u008b\u008c\7\f\2\2\u008c\u008d\5\36\20\2\u008d\u008e") + buf.write("\7\b\2\2\u008e\33\3\2\2\2\u008f\u0090\7,\2\2\u0090\u0091") + buf.write("\7\r\2\2\u0091\u009a\5\36\20\2\u0092\u0093\7,\2\2\u0093") + buf.write("\u0094\7\16\2\2\u0094\u0095\5\36\20\2\u0095\u0096\7\17") + buf.write("\2\2\u0096\u0097\7\r\2\2\u0097\u0098\5\36\20\2\u0098\u009a") + buf.write("\3\2\2\2\u0099\u008f\3\2\2\2\u0099\u0092\3\2\2\2\u009a") + buf.write("\35\3\2\2\2\u009b\u009c\b\20\1\2\u009c\u009d\5 \21\2\u009d") + buf.write("\u00ac\3\2\2\2\u009e\u009f\f\7\2\2\u009f\u00a0\t\2\2\2") + buf.write("\u00a0\u00ab\5\36\20\b\u00a1\u00a2\f\6\2\2\u00a2\u00a3") + buf.write("\t\3\2\2\u00a3\u00ab\5\36\20\7\u00a4\u00a5\f\5\2\2\u00a5") + buf.write("\u00a6\t\4\2\2\u00a6\u00ab\5\36\20\6\u00a7\u00a8\f\4\2") + buf.write("\2\u00a8\u00a9\t\5\2\2\u00a9\u00ab\5\36\20\5\u00aa\u009e") + buf.write("\3\2\2\2\u00aa\u00a1\3\2\2\2\u00aa\u00a4\3\2\2\2\u00aa") + buf.write("\u00a7\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3\2\2\2") + buf.write("\u00ac\u00ad\3\2\2\2\u00ad\37\3\2\2\2\u00ae\u00ac\3\2") + buf.write("\2\2\u00af\u00b0\7,\2\2\u00b0\u00b1\7\16\2\2\u00b1\u00b2") + buf.write("\5\36\20\2\u00b2\u00b3\7\17\2\2\u00b3\u00b7\3\2\2\2\u00b4") + buf.write("\u00b7\5&\24\2\u00b5\u00b7\7,\2\2\u00b6\u00af\3\2\2\2") + buf.write("\u00b6\u00b4\3\2\2\2\u00b6\u00b5\3\2\2\2\u00b7!\3\2\2") + buf.write("\2\u00b8\u00b9\5*\26\2\u00b9\u00ba\5$\23\2\u00ba\u00bb") + buf.write("\5$\23\2\u00bb#\3\2\2\2\u00bc\u00bf\7*\2\2\u00bd\u00bf") + buf.write("\5(\25\2\u00be\u00bc\3\2\2\2\u00be\u00bd\3\2\2\2\u00bf") + buf.write("%\3\2\2\2\u00c0\u00c4\7*\2\2\u00c1\u00c4\7)\2\2\u00c2") + buf.write("\u00c4\5(\25\2\u00c3\u00c0\3\2\2\2\u00c3\u00c1\3\2\2\2") + buf.write("\u00c3\u00c2\3\2\2\2\u00c4\'\3\2\2\2\u00c5\u00c6\7-\2") + buf.write("\2\u00c6)\3\2\2\2\u00c7\u00c9\t\6\2\2\u00c8\u00ca\7\"") + buf.write("\2\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca+\3") + buf.write("\2\2\2\u00cb\u00cc\t\7\2\2\u00cc-\3\2\2\2\21\61BGPT^g") + buf.write("\u0089\u0099\u00aa\u00ac\u00b6\u00be\u00c3\u00c9") + return buf.getvalue() + + +class HybroLangParser ( Parser ): + + grammarFileName = "HybroLang.g4" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ "", "'('", "')'", "'{'", "'}'", "','", "';'", + "'for'", "'if'", "'else'", "'return'", "'='", "'['", + "']'", "'*'", "'/'", "'+'", "'-'", "'<<'", "'>>'", + "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", "'suint'", + "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", + "'=='", "'!='", "'<'", "'>'", "'<='", "'>='" ] + + symbolicNames = [ "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "DecimalFloatingConstant", + "IntegerConstant", "DecimalConstant", "Name", "INLINE", + "WhiteSpace", "LineComment", "NewLine" ] + + RULE_compilationunit = 0 + RULE_function = 1 + RULE_fndcl = 2 + RULE_fnprototype = 3 + RULE_fnbody = 4 + RULE_paramdcllist = 5 + RULE_localvardef = 6 + RULE_vardcllist = 7 + RULE_vardcl = 8 + RULE_actionlist = 9 + RULE_condexpr = 10 + RULE_action = 11 + RULE_returnexpr = 12 + RULE_affectexpr = 13 + RULE_unaryexpr = 14 + RULE_varorvalue = 15 + RULE_datatype = 16 + RULE_intconstvalue = 17 + RULE_constvalue = 18 + RULE_constinline = 19 + RULE_typebase = 20 + RULE_condOperator = 21 + + ruleNames = [ "compilationunit", "function", "fndcl", "fnprototype", + "fnbody", "paramdcllist", "localvardef", "vardcllist", + "vardcl", "actionlist", "condexpr", "action", "returnexpr", + "affectexpr", "unaryexpr", "varorvalue", "datatype", + "intconstvalue", "constvalue", "constinline", "typebase", + "condOperator" ] + + EOF = Token.EOF + T__0=1 + T__1=2 + T__2=3 + T__3=4 + T__4=5 + T__5=6 + T__6=7 + T__7=8 + T__8=9 + T__9=10 + T__10=11 + T__11=12 + T__12=13 + T__13=14 + T__14=15 + T__15=16 + T__16=17 + T__17=18 + T__18=19 + T__19=20 + T__20=21 + T__21=22 + T__22=23 + T__23=24 + T__24=25 + T__25=26 + T__26=27 + T__27=28 + T__28=29 + T__29=30 + T__30=31 + T__31=32 + T__32=33 + T__33=34 + T__34=35 + T__35=36 + T__36=37 + T__37=38 + DecimalFloatingConstant=39 + IntegerConstant=40 + DecimalConstant=41 + Name=42 + INLINE=43 + WhiteSpace=44 + LineComment=45 + NewLine=46 + + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.9.2") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + + + + class CompilationunitContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def function(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.FunctionContext) + else: + return self.getTypedRuleContext(HybroLangParser.FunctionContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_compilationunit + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitCompilationunit" ): + return visitor.visitCompilationunit(self) + else: + return visitor.visitChildren(self) + + + + + def compilationunit(self): + + localctx = HybroLangParser.CompilationunitContext(self, self._ctx, self.state) + self.enterRule(localctx, 0, self.RULE_compilationunit) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 45 + self._errHandler.sync(self) + _la = self._input.LA(1) + while True: + self.state = 44 + self.function() + self.state = 47 + self._errHandler.sync(self) + _la = self._input.LA(1) + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__22) | (1 << HybroLangParser.T__23) | (1 << HybroLangParser.T__24) | (1 << HybroLangParser.T__25) | (1 << HybroLangParser.T__26) | (1 << HybroLangParser.T__27) | (1 << HybroLangParser.T__28) | (1 << HybroLangParser.T__29) | (1 << HybroLangParser.T__30))) != 0)): + break + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class FunctionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def fndcl(self): + return self.getTypedRuleContext(HybroLangParser.FndclContext,0) + + + def fnbody(self): + return self.getTypedRuleContext(HybroLangParser.FnbodyContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_function + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFunction" ): + return visitor.visitFunction(self) + else: + return visitor.visitChildren(self) + + + + + def function(self): + + localctx = HybroLangParser.FunctionContext(self, self._ctx, self.state) + self.enterRule(localctx, 2, self.RULE_function) + try: + self.enterOuterAlt(localctx, 1) + self.state = 49 + self.fndcl() + self.state = 50 + self.fnbody() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class FndclContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def datatype(self): + return self.getTypedRuleContext(HybroLangParser.DatatypeContext,0) + + + def Name(self): + return self.getToken(HybroLangParser.Name, 0) + + def fnprototype(self): + return self.getTypedRuleContext(HybroLangParser.FnprototypeContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_fndcl + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFndcl" ): + return visitor.visitFndcl(self) + else: + return visitor.visitChildren(self) + + + + + def fndcl(self): + + localctx = HybroLangParser.FndclContext(self, self._ctx, self.state) + self.enterRule(localctx, 4, self.RULE_fndcl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 52 + self.datatype() + self.state = 53 + self.match(HybroLangParser.Name) + self.state = 54 + self.fnprototype() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class FnprototypeContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def paramdcllist(self): + return self.getTypedRuleContext(HybroLangParser.ParamdcllistContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_fnprototype + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFnprototype" ): + return visitor.visitFnprototype(self) + else: + return visitor.visitChildren(self) + + + + + def fnprototype(self): + + localctx = HybroLangParser.FnprototypeContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_fnprototype) + try: + self.enterOuterAlt(localctx, 1) + self.state = 56 + self.match(HybroLangParser.T__0) + self.state = 57 + self.paramdcllist() + self.state = 58 + self.match(HybroLangParser.T__1) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class FnbodyContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def actionlist(self): + return self.getTypedRuleContext(HybroLangParser.ActionlistContext,0) + + + def localvardef(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.LocalvardefContext) + else: + return self.getTypedRuleContext(HybroLangParser.LocalvardefContext,i) + + + def returnexpr(self): + return self.getTypedRuleContext(HybroLangParser.ReturnexprContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_fnbody + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFnbody" ): + return visitor.visitFnbody(self) + else: + return visitor.visitChildren(self) + + + + + def fnbody(self): + + localctx = HybroLangParser.FnbodyContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_fnbody) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 60 + self.match(HybroLangParser.T__2) + self.state = 64 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__22) | (1 << HybroLangParser.T__23) | (1 << HybroLangParser.T__24) | (1 << HybroLangParser.T__25) | (1 << HybroLangParser.T__26) | (1 << HybroLangParser.T__27) | (1 << HybroLangParser.T__28) | (1 << HybroLangParser.T__29) | (1 << HybroLangParser.T__30))) != 0): + self.state = 61 + self.localvardef() + self.state = 66 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 67 + self.actionlist() + self.state = 69 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==HybroLangParser.T__9: + self.state = 68 + self.returnexpr() + + + self.state = 71 + self.match(HybroLangParser.T__3) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ParamdcllistContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def vardcl(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.VardclContext) + else: + return self.getTypedRuleContext(HybroLangParser.VardclContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_paramdcllist + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitParamdcllist" ): + return visitor.visitParamdcllist(self) + else: + return visitor.visitChildren(self) + + + + + def paramdcllist(self): + + localctx = HybroLangParser.ParamdcllistContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_paramdcllist) + self._la = 0 # Token type + try: + self.state = 82 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [HybroLangParser.T__22, HybroLangParser.T__23, HybroLangParser.T__24, HybroLangParser.T__25, HybroLangParser.T__26, HybroLangParser.T__27, HybroLangParser.T__28, HybroLangParser.T__29, HybroLangParser.T__30]: + self.enterOuterAlt(localctx, 1) + self.state = 73 + self.vardcl() + self.state = 78 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==HybroLangParser.T__4: + self.state = 74 + self.match(HybroLangParser.T__4) + self.state = 75 + self.vardcl() + self.state = 80 + self._errHandler.sync(self) + _la = self._input.LA(1) + + pass + elif token in [HybroLangParser.T__1]: + self.enterOuterAlt(localctx, 2) + + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class LocalvardefContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def vardcllist(self): + return self.getTypedRuleContext(HybroLangParser.VardcllistContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_localvardef + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitLocalvardef" ): + return visitor.visitLocalvardef(self) + else: + return visitor.visitChildren(self) + + + + + def localvardef(self): + + localctx = HybroLangParser.LocalvardefContext(self, self._ctx, self.state) + self.enterRule(localctx, 12, self.RULE_localvardef) + try: + self.enterOuterAlt(localctx, 1) + self.state = 84 + self.vardcllist() + self.state = 85 + self.match(HybroLangParser.T__5) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class VardcllistContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def vardcl(self): + return self.getTypedRuleContext(HybroLangParser.VardclContext,0) + + + def Name(self, i:int=None): + if i is None: + return self.getTokens(HybroLangParser.Name) + else: + return self.getToken(HybroLangParser.Name, i) + + def getRuleIndex(self): + return HybroLangParser.RULE_vardcllist + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVardcllist" ): + return visitor.visitVardcllist(self) + else: + return visitor.visitChildren(self) + + + + + def vardcllist(self): + + localctx = HybroLangParser.VardcllistContext(self, self._ctx, self.state) + self.enterRule(localctx, 14, self.RULE_vardcllist) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 87 + self.vardcl() + self.state = 92 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==HybroLangParser.T__4: + self.state = 88 + self.match(HybroLangParser.T__4) + self.state = 89 + self.match(HybroLangParser.Name) + self.state = 94 + self._errHandler.sync(self) + _la = self._input.LA(1) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class VardclContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def datatype(self): + return self.getTypedRuleContext(HybroLangParser.DatatypeContext,0) + + + def Name(self): + return self.getToken(HybroLangParser.Name, 0) + + def getRuleIndex(self): + return HybroLangParser.RULE_vardcl + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVardcl" ): + return visitor.visitVardcl(self) + else: + return visitor.visitChildren(self) + + + + + def vardcl(self): + + localctx = HybroLangParser.VardclContext(self, self._ctx, self.state) + self.enterRule(localctx, 16, self.RULE_vardcl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 95 + self.datatype() + self.state = 96 + self.match(HybroLangParser.Name) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ActionlistContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def action(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.ActionContext) + else: + return self.getTypedRuleContext(HybroLangParser.ActionContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_actionlist + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitActionlist" ): + return visitor.visitActionlist(self) + else: + return visitor.visitChildren(self) + + + + + def actionlist(self): + + localctx = HybroLangParser.ActionlistContext(self, self._ctx, self.state) + self.enterRule(localctx, 18, self.RULE_actionlist) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 101 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__6) | (1 << HybroLangParser.T__7) | (1 << HybroLangParser.Name))) != 0): + self.state = 98 + self.action() + self.state = 103 + self._errHandler.sync(self) + _la = self._input.LA(1) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class CondexprContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def varorvalue(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.VarorvalueContext) + else: + return self.getTypedRuleContext(HybroLangParser.VarorvalueContext,i) + + + def condOperator(self): + return self.getTypedRuleContext(HybroLangParser.CondOperatorContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_condexpr + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitCondexpr" ): + return visitor.visitCondexpr(self) + else: + return visitor.visitChildren(self) + + + + + def condexpr(self): + + localctx = HybroLangParser.CondexprContext(self, self._ctx, self.state) + self.enterRule(localctx, 20, self.RULE_condexpr) + try: + self.enterOuterAlt(localctx, 1) + self.state = 104 + self.varorvalue() + self.state = 105 + self.condOperator() + self.state = 106 + self.varorvalue() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ActionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def affectexpr(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.AffectexprContext) + else: + return self.getTypedRuleContext(HybroLangParser.AffectexprContext,i) + + + def condexpr(self): + return self.getTypedRuleContext(HybroLangParser.CondexprContext,0) + + + def actionlist(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.ActionlistContext) + else: + return self.getTypedRuleContext(HybroLangParser.ActionlistContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_action + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAction" ): + return visitor.visitAction(self) + else: + return visitor.visitChildren(self) + + + + + def action(self): + + localctx = HybroLangParser.ActionContext(self, self._ctx, self.state) + self.enterRule(localctx, 22, self.RULE_action) + try: + self.state = 135 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [HybroLangParser.Name]: + self.enterOuterAlt(localctx, 1) + self.state = 108 + self.affectexpr() + self.state = 109 + self.match(HybroLangParser.T__5) + pass + elif token in [HybroLangParser.T__6]: + self.enterOuterAlt(localctx, 2) + self.state = 111 + self.match(HybroLangParser.T__6) + self.state = 112 + self.match(HybroLangParser.T__0) + self.state = 113 + self.affectexpr() + self.state = 114 + self.match(HybroLangParser.T__5) + self.state = 115 + self.condexpr() + self.state = 116 + self.match(HybroLangParser.T__5) + self.state = 117 + self.affectexpr() + self.state = 118 + self.match(HybroLangParser.T__1) + self.state = 119 + self.match(HybroLangParser.T__2) + self.state = 120 + self.actionlist() + self.state = 121 + self.match(HybroLangParser.T__3) + pass + elif token in [HybroLangParser.T__7]: + self.enterOuterAlt(localctx, 3) + self.state = 123 + self.match(HybroLangParser.T__7) + self.state = 124 + self.match(HybroLangParser.T__0) + self.state = 125 + self.condexpr() + self.state = 126 + self.match(HybroLangParser.T__1) + self.state = 127 + self.match(HybroLangParser.T__2) + self.state = 128 + self.actionlist() + self.state = 129 + self.match(HybroLangParser.T__3) + self.state = 130 + self.match(HybroLangParser.T__8) + self.state = 131 + self.match(HybroLangParser.T__2) + self.state = 132 + self.actionlist() + self.state = 133 + self.match(HybroLangParser.T__3) + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ReturnexprContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def unaryexpr(self): + return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_returnexpr + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitReturnexpr" ): + return visitor.visitReturnexpr(self) + else: + return visitor.visitChildren(self) + + + + + def returnexpr(self): + + localctx = HybroLangParser.ReturnexprContext(self, self._ctx, self.state) + self.enterRule(localctx, 24, self.RULE_returnexpr) + try: + self.enterOuterAlt(localctx, 1) + self.state = 137 + self.match(HybroLangParser.T__9) + self.state = 138 + self.unaryexpr(0) + self.state = 139 + self.match(HybroLangParser.T__5) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class AffectexprContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def Name(self): + return self.getToken(HybroLangParser.Name, 0) + + def unaryexpr(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.UnaryexprContext) + else: + return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_affectexpr + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitAffectexpr" ): + return visitor.visitAffectexpr(self) + else: + return visitor.visitChildren(self) + + + + + def affectexpr(self): + + localctx = HybroLangParser.AffectexprContext(self, self._ctx, self.state) + self.enterRule(localctx, 26, self.RULE_affectexpr) + try: + self.state = 151 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,8,self._ctx) + if la_ == 1: + self.enterOuterAlt(localctx, 1) + self.state = 141 + self.match(HybroLangParser.Name) + self.state = 142 + self.match(HybroLangParser.T__10) + self.state = 143 + self.unaryexpr(0) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 144 + self.match(HybroLangParser.Name) + self.state = 145 + self.match(HybroLangParser.T__11) + self.state = 146 + self.unaryexpr(0) + self.state = 147 + self.match(HybroLangParser.T__12) + self.state = 148 + self.match(HybroLangParser.T__10) + self.state = 149 + self.unaryexpr(0) + pass + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class UnaryexprContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.op = None # Token + + def varorvalue(self): + return self.getTypedRuleContext(HybroLangParser.VarorvalueContext,0) + + + def unaryexpr(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.UnaryexprContext) + else: + return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_unaryexpr + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitUnaryexpr" ): + return visitor.visitUnaryexpr(self) + else: + return visitor.visitChildren(self) + + + + def unaryexpr(self, _p:int=0): + _parentctx = self._ctx + _parentState = self.state + localctx = HybroLangParser.UnaryexprContext(self, self._ctx, _parentState) + _prevctx = localctx + _startState = 28 + self.enterRecursionRule(localctx, 28, self.RULE_unaryexpr, _p) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 154 + self.varorvalue() + self._ctx.stop = self._input.LT(-1) + self.state = 170 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,10,self._ctx) + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt==1: + if self._parseListeners is not None: + self.triggerExitRuleEvent() + _prevctx = localctx + self.state = 168 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,9,self._ctx) + if la_ == 1: + localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) + self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) + self.state = 156 + if not self.precpred(self._ctx, 5): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") + self.state = 157 + localctx.op = self._input.LT(1) + _la = self._input.LA(1) + if not(_la==HybroLangParser.T__13 or _la==HybroLangParser.T__14): + localctx.op = self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + self.state = 158 + self.unaryexpr(6) + pass + + elif la_ == 2: + localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) + self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) + self.state = 159 + if not self.precpred(self._ctx, 4): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") + self.state = 160 + localctx.op = self._input.LT(1) + _la = self._input.LA(1) + if not(_la==HybroLangParser.T__15 or _la==HybroLangParser.T__16): + localctx.op = self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + self.state = 161 + self.unaryexpr(5) + pass + + elif la_ == 3: + localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) + self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) + self.state = 162 + if not self.precpred(self._ctx, 3): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") + self.state = 163 + localctx.op = self._input.LT(1) + _la = self._input.LA(1) + if not(_la==HybroLangParser.T__17 or _la==HybroLangParser.T__18): + localctx.op = self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + self.state = 164 + self.unaryexpr(4) + pass + + elif la_ == 4: + localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) + self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) + self.state = 165 + if not self.precpred(self._ctx, 2): + from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") + self.state = 166 + localctx.op = self._input.LT(1) + _la = self._input.LA(1) + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__19) | (1 << HybroLangParser.T__20) | (1 << HybroLangParser.T__21))) != 0)): + localctx.op = self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + self.state = 167 + self.unaryexpr(3) + pass + + + self.state = 172 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,10,self._ctx) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.unrollRecursionContexts(_parentctx) + return localctx + + class VarorvalueContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return HybroLangParser.RULE_varorvalue + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + + class VarorvalueVarContext(VarorvalueContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a HybroLangParser.VarorvalueContext + super().__init__(parser) + self.copyFrom(ctx) + + def Name(self): + return self.getToken(HybroLangParser.Name, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVarorvalueVar" ): + return visitor.visitVarorvalueVar(self) + else: + return visitor.visitChildren(self) + + + class VarorvalueArrayContext(VarorvalueContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a HybroLangParser.VarorvalueContext + super().__init__(parser) + self.copyFrom(ctx) + + def Name(self): + return self.getToken(HybroLangParser.Name, 0) + def unaryexpr(self): + return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,0) + + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVarorvalueArray" ): + return visitor.visitVarorvalueArray(self) + else: + return visitor.visitChildren(self) + + + class VarorvalueConstContext(VarorvalueContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a HybroLangParser.VarorvalueContext + super().__init__(parser) + self.copyFrom(ctx) + + def constvalue(self): + return self.getTypedRuleContext(HybroLangParser.ConstvalueContext,0) + + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitVarorvalueConst" ): + return visitor.visitVarorvalueConst(self) + else: + return visitor.visitChildren(self) + + + + def varorvalue(self): + + localctx = HybroLangParser.VarorvalueContext(self, self._ctx, self.state) + self.enterRule(localctx, 30, self.RULE_varorvalue) + try: + self.state = 180 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,11,self._ctx) + if la_ == 1: + localctx = HybroLangParser.VarorvalueArrayContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 173 + self.match(HybroLangParser.Name) + self.state = 174 + self.match(HybroLangParser.T__11) + self.state = 175 + self.unaryexpr(0) + self.state = 176 + self.match(HybroLangParser.T__12) + pass + + elif la_ == 2: + localctx = HybroLangParser.VarorvalueConstContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 178 + self.constvalue() + pass + + elif la_ == 3: + localctx = HybroLangParser.VarorvalueVarContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 179 + self.match(HybroLangParser.Name) + pass + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class DatatypeContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.wordlen = None # IntconstvalueContext + self.vectorlen = None # IntconstvalueContext + + def typebase(self): + return self.getTypedRuleContext(HybroLangParser.TypebaseContext,0) + + + def intconstvalue(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(HybroLangParser.IntconstvalueContext) + else: + return self.getTypedRuleContext(HybroLangParser.IntconstvalueContext,i) + + + def getRuleIndex(self): + return HybroLangParser.RULE_datatype + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitDatatype" ): + return visitor.visitDatatype(self) + else: + return visitor.visitChildren(self) + + + + + def datatype(self): + + localctx = HybroLangParser.DatatypeContext(self, self._ctx, self.state) + self.enterRule(localctx, 32, self.RULE_datatype) + try: + self.enterOuterAlt(localctx, 1) + self.state = 182 + self.typebase() + self.state = 183 + localctx.wordlen = self.intconstvalue() + self.state = 184 + localctx.vectorlen = self.intconstvalue() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class IntconstvalueContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def IntegerConstant(self): + return self.getToken(HybroLangParser.IntegerConstant, 0) + + def constinline(self): + return self.getTypedRuleContext(HybroLangParser.ConstinlineContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_intconstvalue + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitIntconstvalue" ): + return visitor.visitIntconstvalue(self) + else: + return visitor.visitChildren(self) + + + + + def intconstvalue(self): + + localctx = HybroLangParser.IntconstvalueContext(self, self._ctx, self.state) + self.enterRule(localctx, 34, self.RULE_intconstvalue) + try: + self.state = 188 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [HybroLangParser.IntegerConstant]: + self.enterOuterAlt(localctx, 1) + self.state = 186 + self.match(HybroLangParser.IntegerConstant) + pass + elif token in [HybroLangParser.INLINE]: + self.enterOuterAlt(localctx, 2) + self.state = 187 + self.constinline() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ConstvalueContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def IntegerConstant(self): + return self.getToken(HybroLangParser.IntegerConstant, 0) + + def DecimalFloatingConstant(self): + return self.getToken(HybroLangParser.DecimalFloatingConstant, 0) + + def constinline(self): + return self.getTypedRuleContext(HybroLangParser.ConstinlineContext,0) + + + def getRuleIndex(self): + return HybroLangParser.RULE_constvalue + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitConstvalue" ): + return visitor.visitConstvalue(self) + else: + return visitor.visitChildren(self) + + + + + def constvalue(self): + + localctx = HybroLangParser.ConstvalueContext(self, self._ctx, self.state) + self.enterRule(localctx, 36, self.RULE_constvalue) + try: + self.state = 193 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [HybroLangParser.IntegerConstant]: + self.enterOuterAlt(localctx, 1) + self.state = 190 + self.match(HybroLangParser.IntegerConstant) + pass + elif token in [HybroLangParser.DecimalFloatingConstant]: + self.enterOuterAlt(localctx, 2) + self.state = 191 + self.match(HybroLangParser.DecimalFloatingConstant) + pass + elif token in [HybroLangParser.INLINE]: + self.enterOuterAlt(localctx, 3) + self.state = 192 + self.constinline() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class ConstinlineContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def INLINE(self): + return self.getToken(HybroLangParser.INLINE, 0) + + def getRuleIndex(self): + return HybroLangParser.RULE_constinline + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitConstinline" ): + return visitor.visitConstinline(self) + else: + return visitor.visitChildren(self) + + + + + def constinline(self): + + localctx = HybroLangParser.ConstinlineContext(self, self._ctx, self.state) + self.enterRule(localctx, 38, self.RULE_constinline) + try: + self.enterOuterAlt(localctx, 1) + self.state = 195 + self.match(HybroLangParser.INLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class TypebaseContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return HybroLangParser.RULE_typebase + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitTypebase" ): + return visitor.visitTypebase(self) + else: + return visitor.visitChildren(self) + + + + + def typebase(self): + + localctx = HybroLangParser.TypebaseContext(self, self._ctx, self.state) + self.enterRule(localctx, 40, self.RULE_typebase) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 197 + _la = self._input.LA(1) + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__22) | (1 << HybroLangParser.T__23) | (1 << HybroLangParser.T__24) | (1 << HybroLangParser.T__25) | (1 << HybroLangParser.T__26) | (1 << HybroLangParser.T__27) | (1 << HybroLangParser.T__28) | (1 << HybroLangParser.T__29) | (1 << HybroLangParser.T__30))) != 0)): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + self.state = 199 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==HybroLangParser.T__31: + self.state = 198 + self.match(HybroLangParser.T__31) + + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class CondOperatorContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return HybroLangParser.RULE_condOperator + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitCondOperator" ): + return visitor.visitCondOperator(self) + else: + return visitor.visitChildren(self) + + + + + def condOperator(self): + + localctx = HybroLangParser.CondOperatorContext(self, self._ctx, self.state) + self.enterRule(localctx, 42, self.RULE_condOperator) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 201 + _la = self._input.LA(1) + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__32) | (1 << HybroLangParser.T__33) | (1 << HybroLangParser.T__34) | (1 << HybroLangParser.T__35) | (1 << HybroLangParser.T__36) | (1 << HybroLangParser.T__37))) != 0)): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + + def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): + if self._predicates == None: + self._predicates = dict() + self._predicates[14] = self.unaryexpr_sempred + pred = self._predicates.get(ruleIndex, None) + if pred is None: + raise Exception("No predicate with index:" + str(ruleIndex)) + else: + return pred(localctx, predIndex) + + def unaryexpr_sempred(self, localctx:UnaryexprContext, predIndex:int): + if predIndex == 0: + return self.precpred(self._ctx, 5) + + + if predIndex == 1: + return self.precpred(self._ctx, 4) + + + if predIndex == 2: + return self.precpred(self._ctx, 3) + + + if predIndex == 3: + return self.precpred(self._ctx, 2) + + + + + diff --git a/HybroLang/__pycache__/H2Aarch64Rewrite.cpython-312.pyc b/HybroLang/__pycache__/H2Aarch64Rewrite.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4992e9295775b9fb3ea4eab77616b678de3dd95 GIT binary patch literal 4184 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 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2Debug.cpython-312.pyc b/HybroLang/__pycache__/H2Debug.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc47201e2efa06d87eb07f1845d40d366ea45b70 GIT binary patch literal 3339 zcmbtXO>7&-6`tkplFKD&(W0c#6lJZIGAd<9)Sn$gC|cN1U^58hMs`wEZ6U00lUM>i_&@^zqM`-NAPLF>Jy5j{${|3GMX$YRO&cT@ZV{lp_@-JY3i#5#S#n6( zHP8Z`!_1qR@6Eh<^X7ZIe+q>}1m&Brn%W-)g#Jo8v~V5acnXAvNI?pdMO(}=!w}h% z^=z@rEQ37g8dBK%NZ}rN+8WDTkxzP`lTMOxyw_(IbBYR**p_Y;^J=DzY}ZVub9@$r zhe$=sjDnUu3UePVvx*05j%={Z7r7+w_^!_^sH=tb40~b?AIPMCya9`Wtqj<+1oP0No5we6M}f5!XB=FW|iv+6?t(sbq0<4U1O-B^Z9x@d|@Jy~vTX z^-*lErE4?DJWWTHAhnP|MNcwRT9$5ZcCzYHDAtbD6Syh*} zNI3CXc~#9io|!3kBBz^%R#F{qHCrIl{xulMH&raH<*=ly zcTLGK)qK+L2-Gsix1hPQ!^x(J9Uja2y6Uj7trJ*RO%ltCV1N^p73CT^X<9dQhuhKA zI}Weu`GT4BIh>(p*Bsu|%&hA0=?^u-#KgxAqd1J_aO4OE35AY_UQVYra$9OPmyxrn z?X8*1Q*(1Osq4j6oVy0TafJ`TkW?r5C-X%|Fu?VK-~4kU!cA z4m5*tI~cEiT>trDFy08xSD2RI|IGWqyZdp)`$QP-^r{@`jnLi@=}FH{5B=JxUi?+5 zaeC|p^7yAJS6Y!+^-8r+`{?t#&CywVbha^i@o@N(9l2ClXa&Q~;D{X@smis%+V*dw z_38RYd$Ui2sUsegkG#k)lAS*lo(ZADzVAI1631XGdgVov2z6g{7zFa7EynV+GbkS5$drMgKq)K=!fba zYV{3OeYNP}TN8HQ#Gx>OB^b_7LIfFg3Fj{mrVo+j*`zE+W;=yGp)v>NbGP3^2%m<> z)_HssMcOWs*FB1-43GXzltfXRT@vZ7p|JF6DjcB;mkhcT)5BS;<)uVj_Q5`Z-W-+a zK4k&sgLJglny09|Np9!0a{K#mPFCT|emIM_?6;WB$ZHVjDn84V7*^3ir?bh zTKIzbiZ6?xIryKNmd_GktD|5PR^0?*<|GaH8P+n@SHNkdg9HJKI+t!gC-MvLBr4`4wBV%{aPX=$2 z6GHaYbU8~#ahxo|f(?!jsy47Aq!oi?#ZD5Wjmy`rnWX{B(X*b1-2KCTeT-jmF@66|vPHYxYmr{S%G;3l(205NQVDb|C&cu_?{k z((L2F>>u9!T5DasexS94&}ZTUaraW~OhtSmoOi}1exLsO&f&n1Dt$Iz8!DG zukQL=;elrOoE<(_OVlIvwS%QS?OSH=_LK1Zcj3W@;xEPOe69F2JpK0&Y!8(dj&#Fdq;oKnaVIk>X2U68Zw8BA!zjZgQ&@EGYzq#{Wd!&hm$B7#BU z@;-XOh4^<~oMrg)$KFwXri~`^i|}%-l!Z*TGHwl9Srw5|Oi hPJ=ed%mzslM=ZlI|L`Ja`p;Ox| literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2GenGen.cpython-312.pyc b/HybroLang/__pycache__/H2GenGen.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e40116db6aafdb96a234d2e466940d726aad96d GIT binary patch literal 7504 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 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2LabelTable.cpython-312.pyc b/HybroLang/__pycache__/H2LabelTable.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4547d66a0d85be52550dc86b148c259276d192b8 GIT binary patch literal 2887 zcmai0O-vg{6rTODz5XG~j}uG?WeK9NgaRQng8WpXfrhHcQbW|L1hQH@3z+za>>7f% zjzTM>E^R7EFD8d7>8Yu5>7`P8>a|iYULeA;a){JZZWJn2%BgR5yK}>QYUDn zAj~|biV|9(XFWyzk`A-j^)cmd$S7d>`j5EWIXFH*|^9)cKV{9 z6iWNjKG7d3U0OUH+B*xgSvc1ih0z#|sWArA%V>ZjNhNkwo{TB_vElTjnjDc6(}FcCq{y@oarPqn6P|(pUMG+&ilPjXfU_H> zU{v%Pp$r-A>!xXu(SxOS&j~TIxA1}}hef8~v&NP$1;53I=i`%#THs_gG82~Libxk& zO^HpZ9H?l-wjjJb+clGnE3srmj&G!&Y*Id8R`P8OCym9>$Ro9R8%#o3T-mRq8=KEsfvu# zg0dLZQc<{0E12g5kygo}3f`f`h%%RoCKDo~daW5d+z{e|CyGCjWAlne925jWCCOJ{ zz_MO>C{8dF0FibY$P&u?gX`=A{yuN|Tc1_e=NiuD`mW?g$IZU+&FYCuV@L^CN6&N(<{8)9YR+-Y$ddJ`E=fUu(!~HeLCyC4VKQs zig2=+i+0ARl7hUDjAG%Ea7$Jb1VK}PE+syfN*9YlXJ;oEg`{O-O2R^wm6HyhSgb^1 zDi0?<3?pt@NnIKQ*(*8cOji+&?|>|!XZ|BbYW2>_olSq^!=?>?bG~LgcYSjE`VA9) zH8Eo_AE?X)`^`W#QL}RN9=qcrT03r3QMEQ~22L1*z*hzh{|L?Aq^z9ONCMc|r`7`dO2nMi4It8v0)Z6dYe>Ad z`Bsx}-Q>j_C%*3VewvMeP8J?Y0BG4#11SOcwo-zAV>x;~1?ou(z`>Ys0dfzZ2S|ex zk!>AtFsb-lfm%3>438vfDLB0zJXBU_!oCRFWZ1 zAl-8+6qCh*XF*oU^LRL-0a9Pc3rj?L-J!6Sirxl`+5ixUZS`9Z-H+Jqwm!41FW1;_ zR`(m8JQrByR=Bm+_1^9JQ)d0CEv^IRwz<#-7g`@MxrQh3B=X0MBUXUJaNDFX!si7* zIsto2Qo$!l@g$y)5k4SEH|OP8Q3CgllMzW$$(N9II+dW=g1mZya8Q`hPsp-uy+tay zF^dpJYX-86p0dI&%etC&1B~mPU7ybt+znB#_FXsYs`)3tx@v8GqCwn>%h3e5;+jj| zg6|98q%sZTZfI7OE^tZ$li_LgEuwHB?|DJs6BgaJ6DNt3idk-hF*TY<+1`_w9(eqc zyI`OGJ+%u2|CJ`8!+?@rtT>hT>EsBYgih1&bq!D`eMkq tuwJ#r*5`|(b89!Z*g9uq%bv1cqiK2A>Q>uV+P~>|!q)Eah&^t3@*h*%X5s(< literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2MovOptimize.cpython-312.pyc b/HybroLang/__pycache__/H2MovOptimize.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dd5cc2f81115de81999a3e05d93f1c008143c16 GIT binary patch literal 3907 zcmb7HUrZax8K3pq*v1Ps|6(U_uz=Fq35S7;nh?kZauFd{*J%~*uC*F0<6XD~+iPYQ zsL^u0hdhu|)R;@8o~F6-{yr^K>dphjL%#m_B=qWA``lSICK|r)Du%t5<)4H zkB%Dpq^C-QJueWeh({rcLm?AKg=o%n7lq6m4XuSULtDjJptYu|d{(VywC_ja{H>%c z#DztEv70qWHZIPyvdGGx@@x|G^MW`hu|h(U@my3E!~`p2o{t)#lG&~Bqv5yr5Q14n z3ZLX);}p(&Rj$Y*C}Y)UM4J&Pf9(75=7&5 zg^D>98ZXEWLy0q;G=d7f^3@wrlp>upEmk39#7!Z&#+d7*9t_*-=uR6#OXjj@X~hgH zJYsgmd>W=XJoo)}GfKgq&m8=Ygtzz}962kN&YVp~B#FJuPGT|6iZPBo%aL=20~Xl? zzhDd(?ZCgxo|V{YfQ=Ot1A-)LRnk~wBF1Z0P}Lc9j8AAaoLGh`&631ILe?xel9=Ls z7R@a2u}RHFW+671oW5qA=kbIn@fsya7GSXCdv($OsTk*DVl)!-&&K;M^<22n=O0Z? zVDSc@C=vni>aT!tcQU2f!eJpH$l>tfsY;o_hvPxgV`x4{1$W!B`94!P)dHQP;6AO7 z9Lz&HeSI~s63DsQw;b&S#+7GURi^bh!@g{8+ZbFQT)uuk@U5f%1yh%882x+aH}XG} zzbd&8f4)5)$wsI0QBjSGx$$K7=B(NI3qt+9w|?UAN?}hc~L!e@ww~LziCj|u^^^l4?;yza>0y`06@QRKZR2z7jC)) zK0|@@#;rzNr16WEAp#fk!TzN;c>S*3}ypuVb@90xI`nEeRJZsAL2i5*yuK&l`v7hC~ z1a(Zvjm>QJ&lEf@8;*6yhI8GyX~}!9sNO3%@70`VX!+)GBBy8VwCe24q@JEuzdx|$ z9QfM)&3Sd`<7_CJ+VA#;$XdNy8DT|7pwjFW@LnA8A zG;|&x()~nuFr#9gb{>oj%Gh6H-zdPwFQ{pkAwTF9YKmF}zfn_of0c@fGZ7x( z356N}+Z5^qD7s z9bpL{Y75{&Ju*Qi)ID+RM2aOE(SdSreI;+~d6uj6ctUTw;l9W32*xmZ9bQpaf<8MY zMFS?qCwcpC={qQ5%?_{ptt5H%HJcApGv->&PsYMO$)vlGU zwb>Q_vbDg}EK`MA=flo4w;EfCq|2`RjAREZ#btmoZB3H=H6}?e(7$_yS=L0n{%Jr zjBdGm3*A3hv*tZs)#Kf)+wz=$>1oS*{Hn+Q)RylVReMHrJs)m+epqPqtOmXeWIoB< zR2$#@Do|)_TB}rVJ2qnLvCZCfaplI#!&t39wo}`+ojX0qUh{zYf?0E~*;QNnub9_U97%U1W$m4T=1nQ?Hu6zH zA7mTQfsQ=#h0{(vY7- z7I+tZYreE=c3Ap%&s15Oc3th3j=d3zva}S$9*6m%a=%I T*r6$k`ft@B)v}AA(GC6wAb3Bv literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2Node.cpython-312.pyc b/HybroLang/__pycache__/H2Node.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92fafc154f477e822bdba7512120646442595592 GIT binary patch literal 16155 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 QQ(hIa?{mKxufkcs0gu2TTmS$7 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2PowerRewrite.cpython-312.pyc b/HybroLang/__pycache__/H2PowerRewrite.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33cdab472d7de2e387575e05e5dfbe1d3d91b5d6 GIT binary patch literal 2865 zcmZ`*U2Gdg5Z=8z+ZX4YrcL6csi7CqlpORY4Q&&kAT=!{fC;53Lb3pJ@m&&!^PRJI zX>03BE76C5A{w5ON<}SCP!&WGLckM6LZXNVVj9%2BvK`wcq<7KQlFT;%h`@q*7EG^ zezP;Xvoo{zb1W7`(7yWccJ}cwLVvPB(1dkn%>-r+X-LBcO8GrbVHk4;m*Z1BW^=qD ze8zd4V1#nvRM_J~MkFVuM2`;}b-8FN>hTeyJ}0Flj5suaH1Ryr>aKCVy;Q7#mFQn= zFr;8AJY!DfpvR8@i4FD)7jh$(aY7w2beNC^dy?viULJ=Bdxk8HAyJ<@QON5VU$IZ| z`e1DbFmp&p>?A2p!{5aI;{nxqz^U)}`(F-#j0xG~y5r=3f&m2z$m1M>VJ99Cy@iOF$Y8bjEk6J|Tw2MtO zXkNALV&b{uvO4PMM7|#y?$n;>w4;hhqob;$8qW}75im@$rb9($cu39ZG-4TAGHW|D zV(Ok02Y%E7NWlh^5QyC{~nZA;fIvKHS zo#Lz=f@8_7-Rs*sZsl~tf-~)%%=Pqj@893Ecd#%*tO4EhnIxFmyYU!%@&ziU(^)g? zq|?RL8ZZDFz>3YT{v2AW-!eNsf3g(cd1bN`SAMNmmZkVY+rjInZ-h&|12=K0_xV!W z^NZ38zt?YBmNqYJd3aIkT56N8#7k{mpKLC*JvuGS#FkojLMJV?ZuL4*x-GVq#I{AT zJy_PgDD7KrX}|Q?ymQ&T=-%44>sHI|RfJ=`vv|3&Wwvmom47Z7dj4< zS`Ylzc<^r?1n!2A)U*cMMVWH)zyQ+4PdC3PL0B=7ng$`b6G9NX=ro=vCrU*KRxzK~ zG#3XUT!i4yaOtw$nJyNPSMiX-lg+S-Yymnt7&eVOMZ|9AJz3uA6=3fFC^bf&L6#<=q@F?ukW~( z=q*XT?T;DnqEtk9w+1cw}vOWkuUE zZ5AX7Ps3K;E0j@3B`ic((Tv*G6v^m}S0u`3?S2{?SM3uO2{s%q3qkVO{f7y=Hp1Q- z%7abP$vBbOWY0OR1MM&Qwqn3mD}!N0nG*67GRi7rRyDu}ge3-zWO8}-nLr~WnG9np zCD>0`8KjC2)`Wdcy6*rP`yC+X&>bm0jhE`B3kTjkFw;9bId}Ghvx}`=pS=8e`f7S{ z_tQ5fe?0m9$sbNH#}k((E}Iw4Z#I9|{%!kW{OI%m%+0HpCoWE0-}m*CUp)EcQ#U7n zIs4PuTQ9x2VC8RHZ|G+V!s>V|f(;@l^c>E3=r8 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2RegAllocTmp.cpython-312.pyc b/HybroLang/__pycache__/H2RegAllocTmp.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e834f28d8dc27bf11cda14445c7fa8adb19bea48 GIT binary patch literal 4591 zcmcH-TTC0-b;kDC2HV&P<`uj!n++k82T9121VY&m0afB%0Zmp!tu=TiU}JlnI|Ese z+092jV4EtSRx*54kX6+s%1WD`O8HFxD)k3rB3q-Z6tz+%R8^vhs#g2ebMANy7@DY+ zdL^GZ_uO;OoO@pPjQ{BIlru1X_v>8bFBJ^)XPlVBRzTkN0+MDVMq*=3oE>6W#4RyP z+&W~XxHV>rb3+`(Z83Y?G2~zw3)90$+yh3kKeZT=hMbcQ!MTAGfz=(ot=;nQ_z0l( z-qxTZ$$*s`*x+OmXFx|RY-~3mTbR6U0VK`H%n&OvLl%i0vPzZ*%#cm80^}qcKs&yF z$RXJQ(s%2g-qwD3q$?Iv!h`YT)W2X7Q8k(HB9cTcq9ph`3gI<5o>YiPB64{-4}V#psH zji_52wuP96BPYhZxCgw`H42p4C zul}#bOCbMrc^?}L}9R{`8-@-A=A)v)Gjc;()= zy1!-JeKKDYn6W){=d1DIG9L#TmQF050E#zX_rX%#V%_rTMPT@a=Pig~!e)Nqgo7Uq zj2D2UnGt3hoV{0YbTdD#VVG$P21B&ye%MqPDT^5}BkUB|YnpvnX9Jf;i@{-Xf++>f zVa}cwkZEhm8Z9%aTThU%M@UKR6tJXNv+iJ!4lsfxIOV^@i+3>H!BI4&c`cq4?8FWH z;CwkT2zjp(A4~}zLwBl$ARzl;D%eORQXL8T9*rM1qH_`!F%=Jjz9wJ?MlT zRlC!3TPp$JRBrP9p5>&1lh=hGc{wX%AnTlFUef zXtIFU*r34aWni^Wl6V*B$aA6N86;_&Hhk6A7I;lF{GT)Nje-M1-^3GlOs&heG`f~Bh^~O{A>I3Pq`LVPz zuPjTs!{NLG_nALcx6imX%bBVJGi7;~ zf1!NMb?_Ot453)N>a5)zix?Z!1~U+qG!}tSI-s^d(m^!5r?Rlj!z!pLY!r`DGR)YT zV+q(9c=m`&lZQt8-ze8RqLgy|9CUJ(yb7iue>V|2Cd|cRbi>v7U+lH+*lUBmc8PTc|0!+7LZI?NKaJ2Ym=FtsD{d-Sqv_2$-;U9zDlcyfiOo%*Se=WqrtidDX3nEU7+F4|DC z3{%P04iGfiy~Ic~7T)h$>W2?^3n-p+_T7G(cD%Zw z!*T*TdxgIfNl3*HfJtny6WGer_P?c^R!;yy+I(){t*UcyQ)#2R2`(QZ$cIH97;l^oh3#ZUU;7*jc*0r1=n1E;q!tVgjIrvBNvgcOfBA# zUO>0shQ>t+{f%byH)ti@8c}Z%Y*O_~ydkbCgve@ANl0QMEUP-JAxFP%7n4b7oeB00 z1WT*#yxG;?*Y)xBYeE^lVF;QUT4KX7^!Wge+9eVXEyCjRbBeV{0(fD_?hm!+xO_k?2Uy(FWrsUBJrC} z21uQ=oiAO1W&eslC$wdRwybb@?ZeA?Z{?hp{$l=%Y)$i;xA}E#V9C4aU9o-VdE$8{ zW{zCU*0#-Y`Tsx;@VP)sCeX4n{!GpW+ULshK7YDmzG7i=-6sH^^Bv0g4lNIUbNlh_ zTvJ=7sqMLtZR%e4UE4g)`227`HZlI%TxD~nvN>BRtPHMIp3d`!zNvUzk>yX#_2psF ze9g=$tTR%C0B%yF**2ba&S z)I7fO?A-IZ%$ch%e)5OQnQOPQfzLq8=2N-m?o4wx5HI}xXPM@~xw5ot-nGyJ+TsyB z^PUAUbRc>hRclQ*7NA2RF^QXwMLYFFE)UNO-90*o^F`)IRzRho5dOg+DWluLj?CI{vdkvq$%rlCifka%#s8O2*7I6x^xw t56*Vu_*ckhz=CB)Z3F;e&$9opGpz7E)BHVi4B$U){VeN$!yu%J{~LT><0b$A literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2RegCSI.cpython-312.pyc b/HybroLang/__pycache__/H2RegCSI.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a763dee5fd1e383ded79d968a32858cd80077c8a GIT binary patch literal 5373 zcmbVQO>7&-6`mz``6E(ZN)#>9vZ;+l*`(;mi7ZRD>qw?${k0BlONt8!P1qH8O_Sk| zvP;>bKmj=zC=CdR+>30aL3rpvfqU?!fQ~*EC{TDsrAsW5!bMNHIaZ4TzO-*2EMCV{?3 z&szkB&=#Prf)!S6f(?3m!5(VSY*Pa>Vq$D|nzv90jpZ_#T$YoU7C3QvQ4(c23B#ly zX7kBg$vB_K!_%B3COAHw&gm2VEiD|hK5km)D{%4VVzONRw#elrQS9d?auS!#-8Ezv zh=||}7YuX3JG=xUvT{BY3e`maLKGLdTvp`xtYEwv2HdUWvM6AEl5$>@YRuQACE(1# z%cO%xSttPWVw#U9vk9Wj0Rcop+_LAcF>Qwb-M_&7Y@i~O+Oueok|U3KNE4{Xz=<1$ zic}HBjE{wiCK%QEie?xY=7r@FBh+^qJ#f@@0ggk)eB&vYd@uk$n=zNbBm2HlU2>7S zf?DnT8KshouKkv#wK`k6Ul~z6^5L-ejf?6YTI|VZbMGv**M#(4WF%mLQHfe zd_6Kd%Ux)gGeznEW=MBP_sL|)L?gqV+t%lSH&IW1;22cMQ;wQvReMswHvRRo?$ zRv<1CvTL*~rf+G?G}c(c*D101j11^JoyE!}WX%e2KyhNzn{NFg+p0$teI4@N@kCx~)XZ0|CIE=>;|Cet+dK+fgs_)pBzDK_D zyN@tKYt_${=p9>E{n>eR+csL7d?={?A;mxRfZF$-()V7acSPwL z!SD0FupqXrWCm?tB9ncvH2J*!u-e|IwD)ZeSK80qAN!tx>0LM^(&%JX&c^Ft0aKVJ z&~sgf9x7D>7R+z7$2CHx3RICw?cHBn(IFxQE_1N`^#^E z(_Xa*<|6YsCD297=hPQ8j?vAsh9Yqic^NdoFngfEo+eRW-(!3OoZF;42R6d6Xl-x^ z%Lr*B@iKnK!(Q5j7P4-G%7Y1GHFi8W(fiiM6l!*Nm}0~y@NUJVsQ+P;!$`FNqSiK+PeG_2@6*&!Vv~vv(Vb?wXkw zgc?F&JtSJA1O(Q|kyeh@p{z+7f^R~e24sam&$?B%M`3%)lK@`d96M3ItDYQIP7YU&or93v zI!QgSubbEBs=-rg@RAa|^t7WAoLIN2E>3ZAW%stL7eX?yJ$D}|MW4GmRM&CEb-X-W zafM5fs<&J91{E(xId53?4l3TkCpQ%Duc|acNBzf|AEPF? zYNvPIMgVyq7GrD0|GUdZDglFot%g|#r(s-MsoDHq2EzweP2i(@7i#nyWa?=4hO}hW zoUbE0_;|g-X}re38i)wdT121$SDV&oKj93P*X;apO|3;s(WECrYZHJTwWMh6YLSkc zC^UNv6E9@RsDTeMzBWBYuVot2FwCqRuDj$uxEY5v8GlsBEj+%B4ZjjeZ7 z{l~w|Jj!fF6o0?!A5r`x75}Bu)&0{K75~MGf24G+%62`xTVYRZj&7wY;i+opk>9qw zu!FD{Ey&gWLvzQlM$G*w5RiH_HO*Qn3`KdWiD4H_hH+7-Rth&U)kcaSg#{?~o2DZ5 z6bBoKbeNRQO^mr{l*L$k(h4U07c#G$=4QnBk|ZbZh@2qGarixk%je+N5BN1iFUp{R z<%O2|cb2|ppAFz0qrI==XJb?hwf7ZMULmF z+7VDX0=R4nm#&biDWEt5<+-n&eYi*pKgT6px8mq7TX!76&6y{I>X~un%=ptpDr1l787#u zSWM~x)%56w!wZQ*`swk}zCwD+it}y>e+klILhgs|9{S#7Wo$29Zf5YsDJ#=a9@<6l zc+u`=e49YS<7JOe3 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2RegisterBank.cpython-312.pyc b/HybroLang/__pycache__/H2RegisterBank.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f632f268eecbaa51ae050b2ddd4f4aa5d7e581c GIT binary patch literal 8261 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 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2RiscvRewrite.cpython-312.pyc b/HybroLang/__pycache__/H2RiscvRewrite.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a7d9dc586639dd4659221cb7b1844eb9daa2389 GIT binary patch literal 2632 zcmZ`*%Wo4$7@zU(+8cZGfINZVZg{0G)Pe8_3Mr-H6(q}%NXo&YayQ;d;&i?1%x)fb z7l{LhP(>x}B|)MhoC<7nW$(TfAF2-`$L>Zwu>G&xk_)NgiU$Fb6}JoC+b^L_Kp z_xR2JR$CiH(0=*hb@~%OLVvPJsqtIHrVhjcQjv-^l<-EJz%ch|z6_V(Fk9m^{wJSH z@tTnFC;TogXn~BF5MA1@)ntN+pi2j|P)15f82Qk3q>A^DTJzlJotLQ1;Yjc=Hi<{D z!(Y`WGce+hpsVfg9?WHi4Q)sn)(9*}{oOHTn3U)K{_eP;GEUH=hH_bw@)UbL-kNM4 z0b&6W#BP%CsrVjBaH7kq^_j>am^5wg-)uixf(m$mtQ zplHOm^Y(KcJj%f@5{NqjWsc3a@AR;oQZ$XI@`yp@qh`LbiknqT6G9xAB6Qd=NxuEY zO<5VS2$gr)nD-x5dyksIi0A}I6id;rQfg2~$kMcKIif;SV{s)zoPeRJv9xJ90i8^{ zM2LFvzM-2s7^>)_#NjleM+ApAi8kVhSxvFP#*9;+)=i5}rmVD~Gg->q>)^C0z$ml! z{(RS%ks+D^SL>R{be}(Y=1g~2e{Pr>*NN^CF*u@Y=M|#aoFgWaX+3Qvllj&vW{FV; zre zSBGG|g{`}x;~}8B$x07mNB6V!M(FbUt0GX5BJIF8qtHPRn%Wj(-^IX9HGQ*JR;7jq zv2S9FR~`>M9C$jk-1Dma!isd^+ZcGMrjIhYRM||JFxrI_cI^K-Xb{mbup`*L2Mo-1 zlZkrfI(4JOij!%UyeuR02dgaK$(EV41RWS(-}u13Zx_S^o@r(L0WL!y*R;QZU}$%T zv$^p~<6)h(=iY$mm%!g8ekx|jp!!^_j9cYcT7Z*Y+YO6$*Y$!c#rzI$`{-e-jEiao z7FMhZHeZs!sAAo3mo))K^EMv!4Z@Zi6tK|Ng7!~6$Tcv4$qb8)OZ?WM0fBhfHuF8WiMAg`kAVx z^-<7u>+(SSn!8&bCV)9aw#JB@nxvHImb)H}M)Oj|w%&aGB5Y%%&hf*mp&A*7GjpcH6Zn*&9B`aKfA{BBS~Hzi z_XS|UAKme7Ls>;QEtTBu4;{*i#A&ExvVgd;begJ{St7X+cCDujp|-E}UhMPyagoAT viwiww1c-MW#(2|@aNQp$xQ?3FQ1d!EwT@1%qa*9+#J~I@9Ns|CxvKsHSovhe literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/H2SymbolTable.cpython-312.pyc b/HybroLang/__pycache__/H2SymbolTable.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aaace0efb33822512a1d826ed34ad4ffe4fedacf GIT binary patch literal 4311 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 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/HybroLangLexer.cpython-312.pyc b/HybroLang/__pycache__/HybroLangLexer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bcce46c9bdbc7fab9b3a2f2f204b1b41bb3a5acf GIT binary patch literal 13941 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 literal 0 HcmV?d00001 diff --git a/HybroLang/__pycache__/__init__.cpython-312.pyc b/HybroLang/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ccec25cde21043933408714bdb761a12860a07d2 GIT binary patch literal 147 zcmX@j%ge<81Y74`&jitrK?FMZ%mNgd&QQsq$>_I|p@<2{`wUX^%Sb;XKQ}ceKRGc+ zzcAOx!obADNZ+F}sVLt)H4nn@Nz6;vkB`sH%PfhH*DI*}#bJ}1pHiBWYFESxG=dR` Qi$RQ!%#4hTMa)1J05Lft8UO$Q literal 0 HcmV?d00001 diff --git a/Makefile b/Makefile index e61ec62..9e4d7e7 100755 --- a/Makefile +++ b/Makefile @@ -6,7 +6,14 @@ all: @echo "What action do you target ?" @echo "make buildGrammar # Build grammars (need antlr)" @echo "make DbPopulate # Fill database with instruction sets" - @echo "make clean buildGrammar DbPopulate " + @echo "make clean # Clean grammars generated files and delete database" + @echo "make buildAll # Clean environment Build grammars, fill database and build Demos. HybroGen ready to use" + @echo "make check # To check if your installation is completed" + +buildAll: clean + make buildGrammar + make DbPopulate + make cd ./Demos && make buildAll # Uncomment if you whish to use distant database # DBIDS = --dbIds "DistantHost:DataBaseName:UserDbName:DbPassword" @@ -14,6 +21,8 @@ all: # Uncomment if you whish to use distant database # DBIDS = --dbIds "DistantHost:DataBaseName:UserDbName:DbPassword" + + DbPopulate: ./H2Isa.py -n ${DBIDS} # Create database schema make DbArch ARCH=aarch64 @@ -45,16 +54,42 @@ clean: -(cd Demos/; make clean) doregression: - cd CodeExamples && ./Regression.py ${THEARCH} + @(cd CodeExamples && ./Regression.py ${THEARCH}) aarch64: - make doregression THEARCH=aarch64 + @make doregression THEARCH=aarch64 riscv: - make doregression THEARCH=riscv + @make doregression THEARCH=riscv power: - make doregression THEARCH=power + @make doregression THEARCH=power cxram: - make doregression THEARCH=cxram \ No newline at end of file + @make doregression THEARCH=cxram + + +check: + @echo "[INFO] Start checking data base" +#Later add Sqlite3 database check checking if all aarch are in table if tables are'nt empty + @echo "[INFO] Start check with Regression test" + @make --no-print-directory aarch64 && (echo "[OK] Regression test on aarch64")|| (echo "[FAIL] Regression test fail for aarch64") + @make --no-print-directory power && (echo "[OK] Regression test on power")|| (echo "[FAIL] Regression test fail for power") + @make --no-print-directory riscv && (echo "[OK] Regression test on riscv")|| (echo "[FAIL] Regression test fail for riscv") + @echo "[INFO]start check with regressionSingleOp" + @cd CodeExamples && ./RegressionSingleOp.py -d -a aarch64 riscv power + @(cd CodeExamples && ./RegressionSingleOp.py -z -a aarch64) && (echo "[OK] Regression test on aarch64")|| (echo "[FAIL] Regression test fail for aarch64") + @(cd CodeExamples && ./RegressionSingleOp.py -z -a power) && (echo "[OK] Regression test on power")|| (echo "[FAIL] Regression test fail for power") + @(cd CodeExamples && ./RegressionSingleOp.py -z -a riscv) && (echo "[OK] Regression test on riscv")|| (echo "[FAIL] Regression test fail for riscv") + @echo "[INFO] Start trying Demo Stencil (can takes a lot of time (15-20 minutes))" + @(cd ./Demos/Stencil && make -s --no-print-directory allAarch64Qemu) && (echo "[OK] Demo stencil on aarch64 works") || (echo "[FAIL] Demo Stencil fail on aarch64") + @(cd ./Demos/Stencil && make -s --no-print-directory allRiscvQemu) && (echo "[OK] Demo stencil on riscv works") || (echo "[FAIL] Demo Stencil fail on riscv") + @(cd ./Demos/Stencil && make -s --no-print-directory allPowerQemu) && (echo "[OK] Demo stencil on power works") || (echo "[FAIL] Demo Stencil fail on power") + @echo "[INFO] Start Trying Demo Vector Matrix" + @(cd ./Demos/VectorMatrix && make -s --no-print-directory aarch64) && (echo "[OK] Demo Vector Matrix on aarch64 works") || (echo "[FAIL] Demo Vector Matrix fail on aarch64") + @(cd ./Demos/VectorMatrix && make -s --no-print-directory riscv) && (echo "[OK] Demo Vector Matrix on riscv works") || (echo "[FAIL] Demo Vector Matrix fail on riscv") + @(cd ./Demos/VectorMatrix && make -s --no-print-directory power) && (echo "[OK] Demo Vector Matrix on power works") || (echo "[FAIL] Demo Vector Matrix fail on power") + @echo "[INFO] Start Trying Demo Newton-SquareRoot-VariablePrecision" + @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-aarch64) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on aarch64 works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on aarch64") + @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-power) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on power works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on power") + @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-riscv) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on riscv works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on riscv") diff --git a/__pycache__/H2Utils.cpython-312.pyc b/__pycache__/H2Utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f69dbf9c4fa23244a66e9cc896233d520e53fbbf GIT binary patch literal 394 zcmX@j%ge<81Y74`&ny7ak3k$5V1hC}3jrC^8B!Qh7;_k+7*d#87@`;}88w+-f)w~A zGeXsYC>9`Q2I9|NKw>&W30y9Pv4)|Fje%h`RD_YC1f&iOvOv1fKnfE=WhH|qvtN~f zTVhFKjzVftQGStvm4a&V%l|;2$$X2opeQr1sS7?_wC>3dWr73I69=IMJFg_dOI6zdgK-r`CFS>OsXzX%j6 ztUz2W4I~;E?yzuP;Fg_He34uE3X94e7WQ_JMvso5R-ey6X$DQEBB0M0z?xPv6mf&t soIv6ihfQvNN@-52T@f#k3vx~|Kalvq%*e?2nT>&w`!fp@qaauV0N5o`r2qf` literal 0 HcmV?d00001 diff --git a/__pycache__/SwConfig.cpython-312.pyc b/__pycache__/SwConfig.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..417185eb10329bd2afaff98cb6ffd6a30aae5eda GIT binary patch literal 2594 zcmb_eO>7fK6n?Wm_BwHJ0vJM2(WVJ5E+mGCpMZc6@&kfmiJvsoQduqDO>nTi$*fKA z)
QYfhqr%+W$9C`q8;Z$+u+>1>R3EN{&y(Od-RZe~5^%^HiXb+6!Z)WGcdGC8~ z-kapNy1E*`@#~}c#9k5L5BA{>e|fRIj{wX92WLQoDbUC>&XL4GCmMHi4*>n1109}~ z55zc~8}YhkKFk%lfZC!iJVU!|5VWm}8m|eK2jIi5F7(2;0{}5kNuL`DIQrG7dt7}@ z{8`jI=((Xhhl9cwAP~nmnebvSB%1I+>+vCSjya`Fb{y)Z~zyHT9CM zxJ!}IW*5ifZ`nqe#p~7}2@_lb@}QJ248R9@ZUhTv?Z{NFJx|=kxbp;`=kY?f0!#>b zArB+fUdx8^n2H^^K90YcZJ17IfsEvOX$2~i|MaYJd1B!a*RMNI@ZZ49>2bJ?^Ee3$ z(Lb48i*Ij_*pf=)H@-@knXqW{ar2ffvAmwfyxKLriFoFcu4+291!GiC+YSARq#iXg z{YEye^-*e2JSCWVa>(A~WV)oFrgX~EVSA`^noyIajNP8R(iyp7r1Yc_SCf&kR7dCj zg9kezXLHx7aYj!^dJIkPyRD{1le!r}g6`$FkLGMiQ4;AyMp3MW%C@`3{Fx@gB>XOI zUTAEZ7G~-eIo@}QECd^8uRXZ-OYf6ibFH0o!K2gtiyqkA_zsA#ZMu75@4o5Y`xowB zc-Z{#+)r(<{Ck#o6#Vm-2=&cOr`kgB$(>^O#9ZsixnS21{fnr0imaHd@qTRTCh(Gk zy1(RKh6!T4QZp!JH(shOrxmaUaAWNlVH#_O`*d7}Fo}ja%1Xi(Zt6KROelM(Oy)+W z^=#ietY^-n$f~d8r@X@$nyjZMVIi>P{>0sh`9O0q&^#AtDM&5LD1cSHP~p1|C9~K8 z>+#JKRa-GM3PW-T0K0NI&IDbe)2WVu_f{hg@d98F}^?sZp#i z+HcTqEJ|xpvxmB^TrnGP4wgBu&Zf0%E%nv%&o+qQPBCz}ARR765DgQ{ zUonI4ANzx&C~2%uMX_rXC1q&YBwPCxWh|>E%M!1mXhvL7C~GXrs*$p4q|7Ik8GMfL z6iQA?%}H5vmw+wI-3U{##Brju?2*K_cUy_r`p!edqYOG2M3xbbI2PC$Ml7W!()j*u z+1+u-l*_Q+S%n2#a=XO#mQ!K**p;^RVLe#>($W?1Cp!+U5ZS_ce>7a{&}(6CNZbhs z|0Mxi9HohL#wO}|@zF0(|rvWBj7Vh$a~LDa%2e*7LS48pSE7{ zJKjq5_i84)7XtP7b9Zz1zMDMzR`5-Cz81FPT&R@`%>%{Sf!D&<3w1$!iN*8WG=e-*u_jb*XUq%A2l%!r;~U!QtZIaN$Pc&EQBOnR*Y9BE8&_ iGc5x2asAxi?CT7NU-jqMhwnUxk3QO8tOcQ|6w$xBJU12q literal 0 HcmV?d00001 From fe95af8c5e984332b4b799f6b95b50a9052449cb Mon Sep 17 00:00:00 2001 From: Quentin MELOTTE Date: Wed, 22 Jul 2026 15:47:08 +0200 Subject: [PATCH 2/6] Check --- Makefile | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 9e4d7e7..0a426b3 100755 --- a/Makefile +++ b/Makefile @@ -69,27 +69,34 @@ cxram: @make doregression THEARCH=cxram +VERBOSE ?= 0 + +ifeq ($(VERBOSE),1) + REDIRECT := +else + REDIRECT := > /dev/null 2>&1 +endif + + check: - @echo "[INFO] Start checking data base" -#Later add Sqlite3 database check checking if all aarch are in table if tables are'nt empty @echo "[INFO] Start check with Regression test" - @make --no-print-directory aarch64 && (echo "[OK] Regression test on aarch64")|| (echo "[FAIL] Regression test fail for aarch64") - @make --no-print-directory power && (echo "[OK] Regression test on power")|| (echo "[FAIL] Regression test fail for power") - @make --no-print-directory riscv && (echo "[OK] Regression test on riscv")|| (echo "[FAIL] Regression test fail for riscv") - @echo "[INFO]start check with regressionSingleOp" - @cd CodeExamples && ./RegressionSingleOp.py -d -a aarch64 riscv power - @(cd CodeExamples && ./RegressionSingleOp.py -z -a aarch64) && (echo "[OK] Regression test on aarch64")|| (echo "[FAIL] Regression test fail for aarch64") - @(cd CodeExamples && ./RegressionSingleOp.py -z -a power) && (echo "[OK] Regression test on power")|| (echo "[FAIL] Regression test fail for power") - @(cd CodeExamples && ./RegressionSingleOp.py -z -a riscv) && (echo "[OK] Regression test on riscv")|| (echo "[FAIL] Regression test fail for riscv") + @make --no-print-directory aarch64 ${REDIRECT} && (echo "[OK] Regression test on aarch64")|| (echo "[FAIL] Regression test fail for aarch64") + @make --no-print-directory power ${REDIRECT} && (echo "[OK] Regression test on power")|| (echo "[FAIL] Regression test fail for power") + @make --no-print-directory riscv ${REDIRECT} && (echo "[OK] Regression test on riscv")|| (echo "[FAIL] Regression test fail for riscv") +# @echo "[INFO]start check with regressionSingleOp" +# @(cd CodeExamples && ./RegressionSingleOp.py -d -a aarch64 riscv power ${REDIRECT}) +# @(cd CodeExamples && ./RegressionSingleOp.py -z -a aarch64 ${REDIRECT} ) && (echo "[OK] Regression test on aarch64")|| (echo "[FAIL] Regression test fail for aarch64") +# @(cd CodeExamples && ./RegressionSingleOp.py -z -a power ${REDIRECT} ) && (echo "[OK] Regression test on power")|| (echo "[FAIL] Regression test fail for power") +# @(cd CodeExamples && ./RegressionSingleOp.py -z -a riscv ${REDIRECT} ) && (echo "[OK] Regression test on riscv")|| (echo "[FAIL] Regression test fail for riscv") @echo "[INFO] Start trying Demo Stencil (can takes a lot of time (15-20 minutes))" - @(cd ./Demos/Stencil && make -s --no-print-directory allAarch64Qemu) && (echo "[OK] Demo stencil on aarch64 works") || (echo "[FAIL] Demo Stencil fail on aarch64") - @(cd ./Demos/Stencil && make -s --no-print-directory allRiscvQemu) && (echo "[OK] Demo stencil on riscv works") || (echo "[FAIL] Demo Stencil fail on riscv") - @(cd ./Demos/Stencil && make -s --no-print-directory allPowerQemu) && (echo "[OK] Demo stencil on power works") || (echo "[FAIL] Demo Stencil fail on power") + @(cd ./Demos/Stencil && make -s --no-print-directory allAarch64Qemu ${REDIRECT} ) && (echo "[OK] Demo stencil on aarch64 works") || (echo "[FAIL] Demo Stencil fail on aarch64") + @(cd ./Demos/Stencil && make -s --no-print-directory allRiscvQemu ${REDIRECT} ) && (echo "[OK] Demo stencil on riscv works") || (echo "[FAIL] Demo Stencil fail on riscv") + @(cd ./Demos/Stencil && make -s --no-print-directory allPowerQemu ${REDIRECT} ) && (echo "[OK] Demo stencil on power works") || (echo "[FAIL] Demo Stencil fail on power") @echo "[INFO] Start Trying Demo Vector Matrix" - @(cd ./Demos/VectorMatrix && make -s --no-print-directory aarch64) && (echo "[OK] Demo Vector Matrix on aarch64 works") || (echo "[FAIL] Demo Vector Matrix fail on aarch64") - @(cd ./Demos/VectorMatrix && make -s --no-print-directory riscv) && (echo "[OK] Demo Vector Matrix on riscv works") || (echo "[FAIL] Demo Vector Matrix fail on riscv") - @(cd ./Demos/VectorMatrix && make -s --no-print-directory power) && (echo "[OK] Demo Vector Matrix on power works") || (echo "[FAIL] Demo Vector Matrix fail on power") + @(cd ./Demos/VectorMatrix && make -s --no-print-directory aarch64 ${REDIRECT} ) && (echo "[OK] Demo Vector Matrix on aarch64 works") || (echo "[FAIL] Demo Vector Matrix fail on aarch64") + @(cd ./Demos/VectorMatrix && make -s --no-print-directory riscv ${REDIRECT} ) && (echo "[OK] Demo Vector Matrix on riscv works") || (echo "[FAIL] Demo Vector Matrix fail on riscv") + @(cd ./Demos/VectorMatrix && make -s --no-print-directory power ${REDIRECT} ) && (echo "[OK] Demo Vector Matrix on power works") || (echo "[FAIL] Demo Vector Matrix fail on power") @echo "[INFO] Start Trying Demo Newton-SquareRoot-VariablePrecision" - @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-aarch64) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on aarch64 works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on aarch64") - @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-power) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on power works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on power") - @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-riscv) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on riscv works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on riscv") + @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-aarch64 ${REDIRECT} ) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on aarch64 works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on aarch64") + @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-power ${REDIRECT} ) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on power works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on power") + @(cd ./Demos/Newton-SquareRoot-VariablePrecision && make -s --no-print-directory demo-riscv ${REDIRECT} ) && (echo "[OK] Demo Newton-SquareRoot-VariablePrecision on riscv works") || (echo "[FAIL] Demo Newton-SquareRoot-VariablePrecision fail on riscv") From fac330e6185d5364f820815250117f92050ae4b4 Mon Sep 17 00:00:00 2001 From: Quentin MELOTTE Date: Wed, 22 Jul 2026 15:50:27 +0200 Subject: [PATCH 3/6] Delete file generated --- CodeExamples/Add-With-Specialization.aarch64 | Bin 39832 -> 0 bytes .../Add-With-Specialization.aarch64.c | 976 ------- CodeExamples/Add-With-Specialization.power | Bin 78168 -> 0 bytes CodeExamples/Add-With-Specialization.power.c | 774 ------ CodeExamples/Add-With-Specialization.riscv | Bin 29136 -> 0 bytes CodeExamples/Add-With-Specialization.riscv.c | 667 ----- CodeExamples/Add-With-Transprecision.aarch64 | Bin 43928 -> 0 bytes .../Add-With-Transprecision.aarch64.c | 1101 -------- CodeExamples/Add-With-Transprecision.power | Bin 78288 -> 0 bytes CodeExamples/Add-With-Transprecision.power.c | 850 ------ CodeExamples/Add-With-Transprecision.riscv | Bin 29136 -> 0 bytes CodeExamples/Add-With-Transprecision.riscv.c | 722 ------ CodeExamples/Array-Ld-flt.aarch64 | Bin 48048 -> 0 bytes CodeExamples/Array-Ld-flt.aarch64.c | 1233 --------- CodeExamples/Array-Ld-flt.power | Bin 78424 -> 0 bytes CodeExamples/Array-Ld-flt.power.c | 895 ------- CodeExamples/Array-Ld-flt.riscv | Bin 33296 -> 0 bytes CodeExamples/Array-Ld-flt.riscv.c | 815 ------ CodeExamples/Array-Ld.aarch64 | Bin 43952 -> 0 bytes CodeExamples/Array-Ld.aarch64.c | 1178 --------- CodeExamples/Array-Ld.power | Bin 78192 -> 0 bytes CodeExamples/Array-Ld.power.c | 882 ------- CodeExamples/Array-Ld.riscv | Bin 33248 -> 0 bytes CodeExamples/Array-Ld.riscv.c | 795 ------ .../Array-Mult-Specialization.aarch64 | Bin 48416 -> 0 bytes .../Array-Mult-Specialization.aarch64.c | 1327 ---------- CodeExamples/Array-Mult-Specialization.power | Bin 78720 -> 0 bytes .../Array-Mult-Specialization.power.c | 1052 -------- CodeExamples/Array-Mult-Specialization.riscv | Bin 37596 -> 0 bytes .../Array-Mult-Specialization.riscv.c | 918 ------- CodeExamples/Array-St-flt.aarch64 | Bin 48112 -> 0 bytes CodeExamples/Array-St-flt.aarch64.c | 1233 --------- CodeExamples/Array-St-flt.power | Bin 78544 -> 0 bytes CodeExamples/Array-St-flt.power.c | 909 ------- CodeExamples/Array-St-flt.riscv | Bin 33332 -> 0 bytes CodeExamples/Array-St-flt.riscv.c | 822 ------ CodeExamples/Array-St.aarch64 | Bin 48056 -> 0 bytes CodeExamples/Array-St.aarch64.c | 1205 --------- CodeExamples/Array-St.power | Bin 78304 -> 0 bytes CodeExamples/Array-St.power.c | 909 ------- CodeExamples/Array-St.riscv | Bin 33256 -> 0 bytes CodeExamples/Array-St.riscv.c | 822 ------ CodeExamples/Array-Sum-2D.aarch64 | Bin 52312 -> 0 bytes CodeExamples/Array-Sum-2D.aarch64.c | 1385 ---------- CodeExamples/Array-Sum-2D.power | Bin 78352 -> 0 bytes CodeExamples/Array-Sum-2D.power.c | 1110 -------- CodeExamples/Array-Sum-2D.riscv | Bin 41540 -> 0 bytes CodeExamples/Array-Sum-2D.riscv.c | 971 ------- CodeExamples/CelciusFarenheit.aarch64 | Bin 48128 -> 0 bytes CodeExamples/CelciusFarenheit.aarch64.c | 1306 ---------- CodeExamples/CelciusFarenheit.power | Bin 78272 -> 0 bytes CodeExamples/CelciusFarenheit.power.c | 986 ------- CodeExamples/CelciusFarenheit.riscv | Bin 41504 -> 0 bytes CodeExamples/CelciusFarenheit.riscv.c | 902 ------- CodeExamples/Constants-Operations.aarch64 | Bin 52312 -> 0 bytes CodeExamples/Constants-Operations.aarch64.c | 1387 ---------- CodeExamples/Constants-Operations.power | Bin 78360 -> 0 bytes CodeExamples/Constants-Operations.power.c | 1067 -------- CodeExamples/Constants-Operations.riscv | Bin 53860 -> 0 bytes CodeExamples/Constants-Operations.riscv.c | 1025 -------- CodeExamples/If-in-Loop.aarch64 | Bin 52344 -> 0 bytes CodeExamples/If-in-Loop.aarch64.c | 1471 ----------- CodeExamples/If-in-Loop.power | Bin 78384 -> 0 bytes CodeExamples/If-in-Loop.power.c | 1172 --------- CodeExamples/If-in-Loop.riscv | Bin 41564 -> 0 bytes CodeExamples/If-in-Loop.riscv.c | 1019 -------- CodeExamples/If.aarch64 | Bin 44024 -> 0 bytes CodeExamples/If.aarch64.c | 1117 -------- CodeExamples/If.power | Bin 78264 -> 0 bytes CodeExamples/If.power.c | 936 ------- CodeExamples/If.riscv | Bin 33272 -> 0 bytes CodeExamples/If.riscv.c | 782 ------ CodeExamples/Loop-in-If.aarch64 | Bin 52312 -> 0 bytes CodeExamples/Loop-in-If.aarch64.c | 1439 ----------- CodeExamples/Loop-in-If.power | Bin 78352 -> 0 bytes CodeExamples/Loop-in-If.power.c | 1164 --------- CodeExamples/Loop-in-If.riscv | Bin 41540 -> 0 bytes CodeExamples/Loop-in-If.riscv.c | 1024 -------- CodeExamples/Loop.aarch64 | Bin 44024 -> 0 bytes CodeExamples/Loop.aarch64.c | 1125 -------- CodeExamples/Loop.power | Bin 78264 -> 0 bytes CodeExamples/Loop.power.c | 944 ------- CodeExamples/Loop.riscv | Bin 33276 -> 0 bytes CodeExamples/Loop.riscv.c | 790 ------ CodeExamples/LoopNest.aarch64 | Bin 52232 -> 0 bytes CodeExamples/LoopNest.aarch64.c | 1438 ----------- CodeExamples/LoopNest.power | Bin 78376 -> 0 bytes CodeExamples/LoopNest.power.c | 1257 --------- CodeExamples/LoopNest.riscv | Bin 49712 -> 0 bytes CodeExamples/LoopNest.riscv.c | 1078 -------- CodeExamples/Mult-With-Specialization.aarch64 | Bin 43968 -> 0 bytes .../Mult-With-Specialization.aarch64.c | 1138 --------- CodeExamples/Mult-With-Specialization.power | Bin 78208 -> 0 bytes CodeExamples/Mult-With-Specialization.power.c | 842 ------ CodeExamples/Mult-With-Specialization.riscv | Bin 29172 -> 0 bytes CodeExamples/Mult-With-Specialization.riscv.c | 755 ------ CodeExamples/Multiple-flt.aarch64 | Bin 52288 -> 0 bytes CodeExamples/Multiple-flt.aarch64.c | 1547 ----------- CodeExamples/Multiple-flt.power | Bin 78456 -> 0 bytes CodeExamples/Multiple-flt.power.c | 1157 --------- CodeExamples/Multiple-flt.riscv | Bin 57932 -> 0 bytes CodeExamples/Multiple-flt.riscv.c | 1087 -------- CodeExamples/Multiple-int.aarch64 | Bin 52288 -> 0 bytes CodeExamples/Multiple-int.aarch64.c | 1406 ---------- CodeExamples/Multiple-int.power | Bin 78336 -> 0 bytes CodeExamples/Multiple-int.power.c | 1086 -------- CodeExamples/Multiple-int.riscv | Bin 53836 -> 0 bytes CodeExamples/Multiple-int.riscv.c | 1044 -------- .../Newton.c | 925 ------- .../Newton.riscv | Bin 65000 -> 0 bytes Demos/Stencil/Stencil.aarch64 | Bin 86152 -> 0 bytes Demos/Stencil/Stencil.aarch64.c | 2275 ----------------- Demos/Stencil/Stencil.power | Bin 145696 -> 0 bytes Demos/Stencil/Stencil.power.c | 1955 -------------- Demos/Stencil/Stencil.riscv | Bin 171700 -> 0 bytes Demos/Stencil/Stencil.riscv.c | 1892 -------------- Demos/VectorMatrix/VectorMatrix.aarch64 | Bin 63912 -> 0 bytes Demos/VectorMatrix/VectorMatrix.aarch64.c | 1923 -------------- Demos/VectorMatrix/VectorMatrix.power | Bin 80624 -> 0 bytes Demos/VectorMatrix/VectorMatrix.power.c | 1457 ----------- Demos/VectorMatrix/VectorMatrix.riscv | Bin 62544 -> 0 bytes Demos/VectorMatrix/VectorMatrix.riscv.c | 1230 --------- HybroGen/IsaDescription.interp | 58 - HybroGen/IsaDescription.tokens | 22 - HybroGen/IsaDescriptionLexer.interp | 59 - HybroGen/IsaDescriptionLexer.py | 92 - HybroGen/IsaDescriptionLexer.tokens | 22 - HybroGen/IsaDescriptionListener.py | 183 -- HybroGen/IsaDescriptionParser.py | 1179 --------- HybroGen/RegisterDescription.interp | 50 - HybroGen/RegisterDescription.tokens | 16 - HybroGen/RegisterDescriptionLexer.interp | 53 - HybroGen/RegisterDescriptionLexer.py | 92 - HybroGen/RegisterDescriptionLexer.tokens | 16 - HybroGen/RegisterDescriptionListener.py | 147 -- HybroGen/RegisterDescriptionParser.py | 891 ------- HybroGen/__pycache__/Counter.cpython-312.pyc | Bin 1673 -> 0 bytes .../GenGeneratorFromDb.cpython-312.pyc | Bin 18476 -> 0 bytes HybroGen/__pycache__/Insn.cpython-312.pyc | Bin 8549 -> 0 bytes HybroGen/__pycache__/IsaDb.cpython-312.pyc | Bin 3882 -> 0 bytes .../IsaDescriptionLexer.cpython-312.pyc | Bin 4975 -> 0 bytes .../IsaDescriptionListener.cpython-312.pyc | Bin 7640 -> 0 bytes .../IsaDescriptionParser.cpython-312.pyc | Bin 64046 -> 0 bytes HybroGen/__pycache__/PGen.cpython-312.pyc | Bin 3465 -> 0 bytes HybroGen/__pycache__/ProxyDb.cpython-312.pyc | Bin 15935 -> 0 bytes HybroGen/__pycache__/Register.cpython-312.pyc | Bin 3665 -> 0 bytes .../RegisterDescriptionLexer.cpython-312.pyc | Bin 5102 -> 0 bytes ...egisterDescriptionListener.cpython-312.pyc | Bin 6685 -> 0 bytes .../RegisterDescriptionParser.cpython-312.pyc | Bin 50224 -> 0 bytes HybroGen/__pycache__/__init__.cpython-312.pyc | Bin 146 -> 0 bytes HybroLang/HybroLang.interp | 125 - HybroLang/HybroLang.tokens | 84 - HybroLang/HybroLangLexer.interp | 162 -- HybroLang/HybroLangLexer.py | 240 -- HybroLang/HybroLangLexer.tokens | 84 - HybroLang/HybroLangParser.py | 1602 ------------ .../H2Aarch64Rewrite.cpython-312.pyc | Bin 4184 -> 0 bytes .../H2CodeGeneration.cpython-312.pyc | Bin 15344 -> 0 bytes .../H2CxRAMRewrite.cpython-312.pyc | Bin 19217 -> 0 bytes HybroLang/__pycache__/H2Debug.cpython-312.pyc | Bin 3339 -> 0 bytes .../__pycache__/H2GenGen.cpython-312.pyc | Bin 7504 -> 0 bytes HybroLang/__pycache__/H2IR2.cpython-312.pyc | Bin 9987 -> 0 bytes .../__pycache__/H2LabelTable.cpython-312.pyc | Bin 2887 -> 0 bytes .../__pycache__/H2MovOptimize.cpython-312.pyc | Bin 3907 -> 0 bytes HybroLang/__pycache__/H2Node.cpython-312.pyc | Bin 16155 -> 0 bytes .../__pycache__/H2NodeType.cpython-312.pyc | Bin 1069 -> 0 bytes .../H2PowerRewrite.cpython-312.pyc | Bin 2865 -> 0 bytes .../__pycache__/H2RegAllocTmp.cpython-312.pyc | Bin 4591 -> 0 bytes .../__pycache__/H2RegCSI.cpython-312.pyc | Bin 5373 -> 0 bytes .../H2RegisterBank.cpython-312.pyc | Bin 8261 -> 0 bytes .../H2RiscvRewrite.cpython-312.pyc | Bin 2632 -> 0 bytes .../__pycache__/H2SymbolTable.cpython-312.pyc | Bin 4311 -> 0 bytes .../H2TransformToMac.cpython-312.pyc | Bin 2645 -> 0 bytes HybroLang/__pycache__/H2Type.cpython-312.pyc | Bin 1606 -> 0 bytes .../H2WindowRewrite.cpython-312.pyc | Bin 6098 -> 0 bytes .../HybroLangLexer.cpython-312.pyc | Bin 13941 -> 0 bytes .../HybroLangParser.cpython-312.pyc | Bin 87146 -> 0 bytes .../HybroLangVisitor.cpython-312.pyc | Bin 6012 -> 0 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 147 -> 0 bytes 179 files changed, 73876 deletions(-) delete mode 100755 CodeExamples/Add-With-Specialization.aarch64 delete mode 100644 CodeExamples/Add-With-Specialization.aarch64.c delete mode 100755 CodeExamples/Add-With-Specialization.power delete mode 100644 CodeExamples/Add-With-Specialization.power.c delete mode 100755 CodeExamples/Add-With-Specialization.riscv delete mode 100644 CodeExamples/Add-With-Specialization.riscv.c delete mode 100755 CodeExamples/Add-With-Transprecision.aarch64 delete mode 100644 CodeExamples/Add-With-Transprecision.aarch64.c delete mode 100755 CodeExamples/Add-With-Transprecision.power delete mode 100644 CodeExamples/Add-With-Transprecision.power.c delete mode 100755 CodeExamples/Add-With-Transprecision.riscv delete mode 100644 CodeExamples/Add-With-Transprecision.riscv.c delete mode 100755 CodeExamples/Array-Ld-flt.aarch64 delete mode 100644 CodeExamples/Array-Ld-flt.aarch64.c delete mode 100755 CodeExamples/Array-Ld-flt.power delete mode 100644 CodeExamples/Array-Ld-flt.power.c delete mode 100755 CodeExamples/Array-Ld-flt.riscv delete mode 100644 CodeExamples/Array-Ld-flt.riscv.c delete mode 100755 CodeExamples/Array-Ld.aarch64 delete mode 100644 CodeExamples/Array-Ld.aarch64.c delete mode 100755 CodeExamples/Array-Ld.power delete mode 100644 CodeExamples/Array-Ld.power.c delete mode 100755 CodeExamples/Array-Ld.riscv delete mode 100644 CodeExamples/Array-Ld.riscv.c delete mode 100755 CodeExamples/Array-Mult-Specialization.aarch64 delete mode 100644 CodeExamples/Array-Mult-Specialization.aarch64.c delete mode 100755 CodeExamples/Array-Mult-Specialization.power delete mode 100644 CodeExamples/Array-Mult-Specialization.power.c delete mode 100755 CodeExamples/Array-Mult-Specialization.riscv delete mode 100644 CodeExamples/Array-Mult-Specialization.riscv.c delete mode 100755 CodeExamples/Array-St-flt.aarch64 delete mode 100644 CodeExamples/Array-St-flt.aarch64.c delete mode 100755 CodeExamples/Array-St-flt.power delete mode 100644 CodeExamples/Array-St-flt.power.c delete mode 100755 CodeExamples/Array-St-flt.riscv delete mode 100644 CodeExamples/Array-St-flt.riscv.c delete mode 100755 CodeExamples/Array-St.aarch64 delete mode 100644 CodeExamples/Array-St.aarch64.c delete mode 100755 CodeExamples/Array-St.power delete mode 100644 CodeExamples/Array-St.power.c delete mode 100755 CodeExamples/Array-St.riscv delete mode 100644 CodeExamples/Array-St.riscv.c delete mode 100755 CodeExamples/Array-Sum-2D.aarch64 delete mode 100644 CodeExamples/Array-Sum-2D.aarch64.c delete mode 100755 CodeExamples/Array-Sum-2D.power delete mode 100644 CodeExamples/Array-Sum-2D.power.c delete mode 100755 CodeExamples/Array-Sum-2D.riscv delete mode 100644 CodeExamples/Array-Sum-2D.riscv.c delete mode 100755 CodeExamples/CelciusFarenheit.aarch64 delete mode 100644 CodeExamples/CelciusFarenheit.aarch64.c delete mode 100755 CodeExamples/CelciusFarenheit.power delete mode 100644 CodeExamples/CelciusFarenheit.power.c delete mode 100755 CodeExamples/CelciusFarenheit.riscv delete mode 100644 CodeExamples/CelciusFarenheit.riscv.c delete mode 100755 CodeExamples/Constants-Operations.aarch64 delete mode 100644 CodeExamples/Constants-Operations.aarch64.c delete mode 100755 CodeExamples/Constants-Operations.power delete mode 100644 CodeExamples/Constants-Operations.power.c delete mode 100755 CodeExamples/Constants-Operations.riscv delete mode 100644 CodeExamples/Constants-Operations.riscv.c delete mode 100755 CodeExamples/If-in-Loop.aarch64 delete mode 100644 CodeExamples/If-in-Loop.aarch64.c delete mode 100755 CodeExamples/If-in-Loop.power delete mode 100644 CodeExamples/If-in-Loop.power.c delete mode 100755 CodeExamples/If-in-Loop.riscv delete mode 100644 CodeExamples/If-in-Loop.riscv.c delete mode 100755 CodeExamples/If.aarch64 delete mode 100644 CodeExamples/If.aarch64.c delete mode 100755 CodeExamples/If.power delete mode 100644 CodeExamples/If.power.c delete mode 100755 CodeExamples/If.riscv delete mode 100644 CodeExamples/If.riscv.c delete mode 100755 CodeExamples/Loop-in-If.aarch64 delete mode 100644 CodeExamples/Loop-in-If.aarch64.c delete mode 100755 CodeExamples/Loop-in-If.power delete mode 100644 CodeExamples/Loop-in-If.power.c delete mode 100755 CodeExamples/Loop-in-If.riscv delete mode 100644 CodeExamples/Loop-in-If.riscv.c delete mode 100755 CodeExamples/Loop.aarch64 delete mode 100644 CodeExamples/Loop.aarch64.c delete mode 100755 CodeExamples/Loop.power delete mode 100644 CodeExamples/Loop.power.c delete mode 100755 CodeExamples/Loop.riscv delete mode 100644 CodeExamples/Loop.riscv.c delete mode 100755 CodeExamples/LoopNest.aarch64 delete mode 100644 CodeExamples/LoopNest.aarch64.c delete mode 100755 CodeExamples/LoopNest.power delete mode 100644 CodeExamples/LoopNest.power.c delete mode 100755 CodeExamples/LoopNest.riscv delete mode 100644 CodeExamples/LoopNest.riscv.c delete mode 100755 CodeExamples/Mult-With-Specialization.aarch64 delete mode 100644 CodeExamples/Mult-With-Specialization.aarch64.c delete mode 100755 CodeExamples/Mult-With-Specialization.power delete mode 100644 CodeExamples/Mult-With-Specialization.power.c delete mode 100755 CodeExamples/Mult-With-Specialization.riscv delete mode 100644 CodeExamples/Mult-With-Specialization.riscv.c delete mode 100755 CodeExamples/Multiple-flt.aarch64 delete mode 100644 CodeExamples/Multiple-flt.aarch64.c delete mode 100755 CodeExamples/Multiple-flt.power delete mode 100644 CodeExamples/Multiple-flt.power.c delete mode 100755 CodeExamples/Multiple-flt.riscv delete mode 100644 CodeExamples/Multiple-flt.riscv.c delete mode 100755 CodeExamples/Multiple-int.aarch64 delete mode 100644 CodeExamples/Multiple-int.aarch64.c delete mode 100755 CodeExamples/Multiple-int.power delete mode 100644 CodeExamples/Multiple-int.power.c delete mode 100755 CodeExamples/Multiple-int.riscv delete mode 100644 CodeExamples/Multiple-int.riscv.c delete mode 100644 Demos/Newton-SquareRoot-VariablePrecision/Newton.c delete mode 100755 Demos/Newton-SquareRoot-VariablePrecision/Newton.riscv delete mode 100755 Demos/Stencil/Stencil.aarch64 delete mode 100644 Demos/Stencil/Stencil.aarch64.c delete mode 100755 Demos/Stencil/Stencil.power delete mode 100644 Demos/Stencil/Stencil.power.c delete mode 100755 Demos/Stencil/Stencil.riscv delete mode 100644 Demos/Stencil/Stencil.riscv.c delete mode 100755 Demos/VectorMatrix/VectorMatrix.aarch64 delete mode 100644 Demos/VectorMatrix/VectorMatrix.aarch64.c delete mode 100755 Demos/VectorMatrix/VectorMatrix.power delete mode 100644 Demos/VectorMatrix/VectorMatrix.power.c delete mode 100755 Demos/VectorMatrix/VectorMatrix.riscv delete mode 100644 Demos/VectorMatrix/VectorMatrix.riscv.c delete mode 100644 HybroGen/IsaDescription.interp delete mode 100644 HybroGen/IsaDescription.tokens delete mode 100644 HybroGen/IsaDescriptionLexer.interp delete mode 100644 HybroGen/IsaDescriptionLexer.py delete mode 100644 HybroGen/IsaDescriptionLexer.tokens delete mode 100644 HybroGen/IsaDescriptionListener.py delete mode 100644 HybroGen/IsaDescriptionParser.py delete mode 100644 HybroGen/RegisterDescription.interp delete mode 100644 HybroGen/RegisterDescription.tokens delete mode 100644 HybroGen/RegisterDescriptionLexer.interp delete mode 100644 HybroGen/RegisterDescriptionLexer.py delete mode 100644 HybroGen/RegisterDescriptionLexer.tokens delete mode 100644 HybroGen/RegisterDescriptionListener.py delete mode 100644 HybroGen/RegisterDescriptionParser.py delete mode 100644 HybroGen/__pycache__/Counter.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/GenGeneratorFromDb.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/Insn.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/IsaDb.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/IsaDescriptionLexer.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/IsaDescriptionListener.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/IsaDescriptionParser.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/PGen.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/ProxyDb.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/Register.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/RegisterDescriptionLexer.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/RegisterDescriptionListener.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/RegisterDescriptionParser.cpython-312.pyc delete mode 100644 HybroGen/__pycache__/__init__.cpython-312.pyc delete mode 100644 HybroLang/HybroLang.interp delete mode 100644 HybroLang/HybroLang.tokens delete mode 100644 HybroLang/HybroLangLexer.interp delete mode 100644 HybroLang/HybroLangLexer.py delete mode 100644 HybroLang/HybroLangLexer.tokens delete mode 100644 HybroLang/HybroLangParser.py delete mode 100644 HybroLang/__pycache__/H2Aarch64Rewrite.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2CodeGeneration.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2CxRAMRewrite.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2Debug.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2GenGen.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2IR2.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2LabelTable.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2MovOptimize.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2Node.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2NodeType.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2PowerRewrite.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2RegAllocTmp.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2RegCSI.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2RegisterBank.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2RiscvRewrite.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2SymbolTable.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2TransformToMac.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2Type.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/H2WindowRewrite.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/HybroLangLexer.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/HybroLangParser.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/HybroLangVisitor.cpython-312.pyc delete mode 100644 HybroLang/__pycache__/__init__.cpython-312.pyc diff --git a/CodeExamples/Add-With-Specialization.aarch64 b/CodeExamples/Add-With-Specialization.aarch64 deleted file mode 100755 index 0bb07df5ff33162aec601d321e1849c08e3e6031..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39832 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -#include // -*- c -*- -#include - -typedef int (*pifi)(int); - -pifi genAdd(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genADD_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -int main(int argc, char * argv[]) -{ - int in0, in1, res; - pifi fPtr; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 & in2 - in1 = atoi (argv[2]); - fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions - printf("// Compilette for simple addition between 1 variable with\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genAdd (fPtr, in0); // Generate instructions - res = fPtr(in1); // Call generated code - printf("%d + %d = %d\n", in0, in1, res); - if (res == (in0 + in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Add-With-Specialization.power b/CodeExamples/Add-With-Specialization.power deleted file mode 100755 index 2b39fab45ffaed3d199fd4464e571ef21faf7c55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78168 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 KPR&I* -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -#include // -*- c -*- -#include - -typedef int (*pifi)(int); - -pifi genAdd(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x780F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genADD_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -int main(int argc, char * argv[]) -{ - int in0, in1, res; - pifi fPtr; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 & in2 - in1 = atoi (argv[2]); - fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions - printf("// Compilette for simple addition between 1 variable with\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genAdd (fPtr, in0); // Generate instructions - res = fPtr(in1); // Call generated code - printf("%d + %d = %d\n", in0, in1, res); - if (res == (in0 + in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Add-With-Specialization.riscv b/CodeExamples/Add-With-Specialization.riscv deleted file mode 100755 index bf3a43a6afa1065502cd2044874f927bb40fd210..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29136 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 P<%|3kW23dq5WfEg_7Ue( diff --git a/CodeExamples/Add-With-Specialization.riscv.c b/CodeExamples/Add-With-Specialization.riscv.c deleted file mode 100644 index c280d38..0000000 --- a/CodeExamples/Add-With-Specialization.riscv.c +++ /dev/null @@ -1,667 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -#include // -*- c -*- -#include - -typedef int (*pifi)(int); - -pifi genAdd(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x73F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genADD_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -int main(int argc, char * argv[]) -{ - int in0, in1, res; - pifi fPtr; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 & in2 - in1 = atoi (argv[2]); - fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions - printf("// Compilette for simple addition between 1 variable with\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genAdd (fPtr, in0); // Generate instructions - res = fPtr(in1); // Call generated code - printf("%d + %d = %d\n", in0, in1, res); - if (res == (in0 + in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Add-With-Transprecision.aarch64 b/CodeExamples/Add-With-Transprecision.aarch64 deleted file mode 100755 index ba791eed19985442f5601c0deb43e65c871b34f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43928 zcmeHw3w%`7wf8=AW-^m^NFr}x!lNRZ1kfS~mPr7Sf(i+~uC0?vGD)T;Ght?eQTXbh z*jn+nU%^K!Xm6>tUrk%DL9Mk{?k%loZLg03wYAlLrM}Zj=l<7z%b1K#NZc9QeJ@W+*dmtATx=Gb z$+7^k;^*Qy6pEM%KbEXj=#Y3OLZVw_5r9P&7muiLiU2beDhVmH$vhFbWJ-jkO(Lm6 z#%m+)BaxmK zUwvh3V|lC3-_cp_@dO)M7M@)Z3RKJ&^(Ov=yXvA#cuCaWb{-QqN*CgnhhH{+`S_(? zL|=d(wKvsG*$nX^J?G$;iyw(dKf)y%t_L9~m!9B@-`zeHLBAKF7iY*NUYX!a`+;BD z4}5(;@YDK%|1ZFu_@!Qx0mvi|=`R!f^Zme`{lJMwCO&8N178mKI5v@WwpSr0+J#5F zoxU(@_XdN3AZzakhv?SO;t4WOeISUOpwAy}V$I%gyQkS3@?Ga;ZSBE8*xL|hZJyTF zKm!Yf8$r&Rt_k|WUgil0nwZ-SvukjN!k%E*-RAN68KueW7P3`qS6450FQ}M*4$zw0 z0)C0+hBy}OUvf&CH|)k>Ex=U$;+tK!qvKgaJ}!lXPGY?-~7bh<0k96im_eCHy?Pg*L1(A=#C+8 zKVyf+{c}}c(a~jHPRsNcr#sCT)DL;b##vl_MHa^McsdK|8Cp6A>1r)qfONfziT3GB5fjVKC}H@E7De^tw>v6 z-2U$4vDh~c;@1uRvSX|IT#P;XbSyT3^sn@bykjhCbnQV{hHx2UZ}(zaD`RYbS<9+E z4`_~=#y*C2A-Yt2;5|3vlk17DQyQJ_ z>Oub;7ezW+i1-$xgz_mqow1EZEVhAgK-Wbwt1=1y$Q0mB5qRjx9M3}ZfPv@wBPN?0 zH7#@BgFL((44=fa4m#w4gdx(S(&Z+@KD5i<21nZSCE zmY_^CQWHH5VTr3JIuo!$7xG*^oJaSPE zQun;E#ZuzhGQ9*kUlTQrxhy=b7Nb!v>zrO&1sK|H;{mD@XpeyQ0BDUZWp|W;whXik zv?y;)T=wXau5~DvbjsymOS{&R9H1v%kSr9Z`rq=8*anvoskuPOc?Rn#B{|O+zMQ-) zls%t#fu5HIeiWy&zI0raRgU~4q?4Jho^K#d<pmn!ZQdDHa7z{?{fA|Mw`w}i^WKFQXFjgE^d8{Wb; zWV5HAC|;pIa=&N;n&3BviK&yfDNrpgIC zC1=!h&V{Twx~yDZvaeBlxS~s5h}v0S)b8q2dQ9pQ==(>|$I)N=Ap3Ldlj`TmCOOYu zk`4V-=AT*0cI`yH*cR8$=mhYbfPQ1L=Opbd(UN3dN1;#T??XT9+XFhPPcQl|%GuAl zmv*%iFX-h<2vr#+D1(;`y`lY}H&(-@ihdtay1>|oygu01K8rQ-n=*{goF_Z4YcqI7 z!1EF+kB@P}Hsj+C#sQL-@>P2r-~3ZC4%QlbKe*De_e0aM?>+E-A7kwYre$B9MYP2M z$X-{BxRuTKAl?Z3uPbIf5iLKW<$nSB5#)nr@$~zRja7Eg7l1y(HolXEcn;^aaVy0o zk21vL{A{pMf?L@}55>n*pNZ5s#kg@b7F5M$_^}mR|Aj3rsx?ZBido&hnliFq;2y;| z=K?O6d8JcKmn5VW&7*I=-Fb3Eq3 zl6^DsTzf5fZ0`(*tIy(KePt6N+eFs$5&8*u^7}rDzBIlG?20Cy6$*54+6{ zVfUuD*`cyww%ILOedBG0`i@SU{ctF4HsU&5fjU6PJ6QL5U7L=}b(S1^IlS(3UG0F^ zNxR!B#-Sa|wX6$!0zq51tjh!2{Uhdc5Bh06?6m>?=nt^{H?aM;o4J(BMp@Vys&@9T$emBx1=_`ddK zw)eFh*7w?EhILP*rq_ZnA7L?D%+omxYXPJS5Mn$9yyv~zDvXcSdyjAaIiK&3Z|)gz z+~l%j?Al|>K8|=5#nt#=;eDKs6bmoDo}$odpyeciOqeG0NZ z2{{iyMzlxq0m#@pp2lO0L27(S8M8kk8yH~B{wuYmHfG2BgOert1L7w%hDCPNu%{mw zlm4)bbfEOC#$mk!dQ;pHn?x-v_V{k6oX;H`c)VV$X>^eDrzCV%oz-e~L8LsL>}_Ps2apH+u>`rt7o! z#%h84kXTPgcZ&6NwARAc)6qM`dOCWKSWidq!(RF+qwC01mahKx($VF}A7HPIa=VT! z@1OoC&o{cLoVUQ|b9S~%wf_OEi>a?FU&egYgRgu0SvQ}Kd|EdvUGe!II+*Tc8z06T z&-eC-(|oVWp!t&P6a8(gSoiaJ-hl6cv9H&#$R56q1W(-uF@*X4lmUGZU((i%8Rc{h zSI)gBMNU^HIU(B#=`%w5%qZvn6#u~fbpOD>`W!!)oS3_Z-0ob?jO{*RIp5LN81Z(G zX!;zEoa`GXO`lI@k`r@qyxp;m7`i@5&Xc3h-I|<7)VklPtvfMJmI1E%`vDpUWmO)rSMZf1Gs7jTK_XTLzRAN9*3WLsOxkC z{!&f@KlNkaTPMfo{`h*Z79NWKyG-MIFZezIfASOXCqE(m$=%YQ+%5gd-O``jE&a)W zYyRY4@pXDPoeL(PWyIGiMkme^pZiJBV2qy$i}T(w@jvJ4dyt{{pX;owv|H{es>sJJ z=fNX%eu;Tdo$JzmCQ{E9i!-&-e$Uj_f*qCwu&{N`!kNd~PS_btU;ksau zb4oMe2gz6m*GTFh*5N0+4$ow&1LTgc3r5lo2gjxkw+&W@k@y7@0e<9#`z z^@EZ4We<;y4Lz^zu`||TB>mvC+y+>0oFxDLBV!`}I3@pXV`ID@xU{}}!u{Ze8usjv`tpd|AgcDd z{nf#FqH7DP!`SqL?`NvRsEn!K#xoFO(+*!AtPUq^OH_xkX@?63s{_^zW!l=}fVQ?6 zaIMX5LLG+mJl%-hQMmJ?MRUROU9=($Lo0BW{PE3|5Dc*wVqVv8DL=FWTXR z=jV)T?Xj8P==_(FKc~*7f?{Ln4mArZ2tNUI~{QNih`EEM@RnK?x^Is`@sxRan zYKH-y6?}vAshx>#)%Jd8s=XiP7#fr7WEnIjt2QtwuJ4y3H`cIGTdNOzrgxpbXCnFN zESKhYijyy!#sZ2f-O%~1szd5ou2bw&>!>aXfA0{+tAS-)ugSPa({0?}4&5HnWZa54 zmr=@2zA?7NR>Gelci3=a@};2Wq(ht!ST+5 zq3Jz-J_)^7X?mx9zp{<3skQ-~M|vL$k{@HVb^J?BPHqQ7wPDzYhvbxcG?wCdgmvOs zzR{Kue(?ByETb-A2Se8-#)kvKeswt`G@odGbIcjX()aEI_q9!f$qAheUCzvHJ{oea z9Zb$)>67FXeQLDzIYW~(Zkx1Tq<%B(@l~u%Mq9={wJt|LAC`<6`;U13Z?t7Rq{$fX zKhR@*EE=X=vIFU3(P-G^cLtMln09%x`g#0WXsn;(`oz3{Li%Jk$M=w<-R?C?pTm_C z_Q2;L8rv@@sWqmS;8`>HP2^s8wB?+m$+<_HD^Glla`%wdD5GJsecFC7ZVM;cx5yUc z9&ogE{Hqg{vp-unNpfa<#sa>+Th(3w@iL05HMLr=GOR}s@0Dh0Bny?}d+OV`1F>(H{r0|8CM7 zaLE3-2lQuNhon9{wD*@s zqYgjKR0rKxdBW{*58B};W6};M?VaQZwZq`=B#%ZrNMGL}7PWM(|38_>p*4Wl4KiK~ z^_eU~_~iI_aUPX72;UPKhfV|E?m_qt)7Qu49S6Q6^YvvO--hbz`x~{x0KUFIkv=tF zpP|ME%<1v9Gv>)Ej9scd2lR{3`wur~+{+(I*~=dq?p}VLw)e~^CuAO;oEi7XBbGBO zlbq0DT%W`8Gm$<|j+`&6HNNf-)8!nFKI#33lhp2yWRf$Y>2o-HPoH zyK^~DPCvRTlbrhgXgK<$HOxtB_p>!Q4`}03E5)U+iH`$v+}?vRO3e*44)hWnYXTat zdTHII-fy1s-9exEh|oGadCfKK@yeP>e)O-A%m4i`k^iu^-iqrV{chy)|9DK~zke|K zVdulLAJ@2AW8%1Cw)=rGkw4>}br|biZvRZI*^~C&^nT2(gTEIr8ht?SS@B&gv+J3+ z`C5_hU&Xh>@Le11S$hGmOI~~J(Dtmr8TOua2kluOq4EadJIu8r=X)pkj?SL-Vet*W zW%v%&HT14+@!r@Sc-MA`(bJoUZ~5)Cig#?!FnXfb;Jw^RgMZT|dX53yqP?;0z?~v- zOC)Zt#4VJ#B{G~qGzEKOn?dsrd{2h+HwFK<@y;&s|Eqk*_al-eZ*S~s;QqJ7Es?l* zXPD#u3g4r_xALOTOPb#jP0rrfm7u|U#Dc$kM;Px8bDHn79)|DPM1KfcIldlQ=7PJP z_3<=(8D&`OBfa>m@8H{Mc$b;OvCkkJ6L}V%k8)qTr+6}O=Hn;cC&u@@`uTPjf1mh9 zYybK94&M>8|NNtrk9Ur#oYzeg?;M-^zKJvPVw4@b-my2f26e`J&~%O;y%8b4Hxw
EIU<9kEVZ^*jugf58Rjf2RGa{8?ge}8&__oFGF%gef6M>!<#2Y8p|53pM*`z`48 zO2~hd`iE=>e5+5kfys3(+JoW}j=7N9pe&_b81l>TeLcOM6i>>dHjJW;Cs8{gJihs` ze0N>=Yxwsv@vT1kh9S+>2gQ3q@Kag4e)4DW9lhNMqxe=IbJF)oU48cx+*LmkK;`IH;bvvnXHfE3n@OG^%>L_Ga)m+VMlosKeER4c=Te|(+b9`QsOL~oJwL`QiB=v?^m zGA6L&dKrXsbb{+R;c))o$N9T#U0bP6uq*X#D*E;xeM^%<^}7jec;6v>TMFMeoxzs8 z@H)Qfb?+h8^OO-ir+)3a=eL1=oAb%ZH(1$v3!8C^n;CB(g`T(Jdxykh#^&4?s+o2B zGG=-EL44Qro+aiB_k!P1uZ=pkMBMYH~g38R+Xlw+!EK{Uvx1y|W|t1$_4y z^ej&Q+A{I&O3FXJ`DgL(6zqcDc0GAc7k!WLHpG8)?>Sw&ET=s8A->J{QG>bnBYeBy zV|=?{*FTr<%t775279!GMSeqk?z=AZ@lkW)zEBqR*9rUZe$m`IwAnqDlDE;G8`O8a zK5AHwZ+Sh9*7jpw4qm9rZvXE%!fT&9FPmsAf$pg8_z zL&0V&j$gH6#ZV~X_!nL}6!ZlD+M40v4-K8I@@?`u7YOBspvgJ28&7x6ogsLU;_}#|W+H4&D1=u~`Tm55;0j5jqjl z-ydoQH51!j>PzV!a59einjC1aHJUg@a0y(4g=;w$Ut`yu<4Hk+>hTUfVWFH@%xuoU*Wtc|7rZz zqK&9cKsWEMth;TND+EF*KyTo;8*NmF5cx%yf|6wT1ivWYPK0z3uOjex2e1bTAZ2fn zWf8A=$Pc5P>D%;_e>r#&ob2Lhz)5dZ#tJEWorJ$H;9R!Nn(SmhyI~(xwkmI>%%1~L zH}ZEOe-V9DzN%o|T{(AWFW>3dWxp-!cAL4{c=eSRUVQ#=0VCXl!0rAw$W9hrRnUG{ z!QJ`GcjoQNy)EbVZ1Vw&!licn7`Rh=fJ+~TuPQiZ+%@g)Q~I%8K0Xg|x~M#|;r)Qk!D)GVc{f>Ad4$^n+=pL8zbfRoDfRewQ^%z~aO<0} zWipPmI-iwPXX+=eKgVK+voqng$E!j5rM~nQJ`DZ|Lh$Xi+%@O!(=3m3ZBu?8`p(lI zLf6oZD%Y}BGzPWtnaGc#kC9mFBKQixUjqD21w=@CqCQ&paV)ll;8g{#yBv4ht9NGY zvMs;Odb_#uo0i>1?W?c+_9fARLeD!u^Dt=iGKl=s>r)MUs)0{6@Tmqq)xf73_;BwnEsB-d+8Dy1`1=FWdWMhpBR`TE6^T=N$ZXxYM23R4=GddZoRBXe*)d zUb~BvZb)Sy(`08BR)M=}p=3mn|2LRl=KQssem=}k~XU6|F%w3efL*n0=iYU`UKbv8m0)O6BE}pZkAN-|&Ti6tstHAG; z?JZLH>rj$jrBm6=<@5w~a8p+8q4Y#KG!}dwKO^!4s)-NxAnq_O27X=)ZAsZz;%6}& zryyyu*xMjM z0IvPR(g%>RX3wOYzLJ%wwS(onz&X;rU@9_-K8xE_yJ0xCAd*FYB+G6Zf@jvdRDjhG zOtb!#QZ}Q2TE&`m6=7x>r_3d`S-+$_yU3f!a!x~LzJu-sTX8G&B0J|+4y1d*?F6J| z%-O?%bT4>_fR_{Se{&$+u~P>SC;lvlY$)GB_ktG)cn4udIgsuJe~qi<65Mjrh;MZb=yc^hK(Y23ISpP)3WeY%61Eqe`RlofspaiHN7 zFU-EV_{Tv=(3%*EtY=XIr$P)90H>!rUG1PE z7GjWG4ycuRImRu>$@@A)Al0SL6~6|G8q?%3sRm7bR8hq{)Br2SKRKkzVN{K}MYfwz zk{p377OS69R!HGkz^?23WCk#us4uCieFX}!DdY$ylnGOJJlDMHxhJq;eR1s zf{GR5$Lx-0aCc;jCbc{M8>wv3bUB9+XLkY%e>sj<@HH^V+lL#OQRK>C5%zY<9Rs;tsYhr z?DrftlSJ8rG#@`7;IMfFdk?U`;8*A&*kwg7z^b6KW%w1fN&#rmMAuC~9Oq-k<%Oi0 zR-iQESG+@_l^E+RUqJ({w|o`%8q3WJmc8D?_>x8TlBwdFch`aE!td6txtazoIx#Da5!5LMB;6v0enMTuLl+OV8G-cC(Rd zp>0#DCUl%-lL*C3sK6>D1`$+xNmgcsLe=(ErD`mwZct{0v1}4oG-`6%B%*Om{ATqe zu2~y19YWEoODq$9T#Xj8C*v>Whz=W9PxjYtFi?%#swd5d7ISX70msl2yQ(32ZUtL5 zY3U??fhsAv!f{FC%%Q0iVN3`Uw+AVVRSL*kl2l~VwI-3Wl3+lxt5$V<24Z94W9T*;|N!3!TKP+(o%@kzN z47#-96K}erTr^IxomzGrvZ-Z-;zY|9i`Ij+Y7JKkARA{;d!CZihM?qam}-ACd6{fJ z?pEU;1^LXtMTq!cQBfJXHq_{C4^_&)kk0T|t?{?3D{3hpO<_^{DYM*|SvC{@&GF7P zYu3-S;15z8{|OY6(Oi;=b$cM>>#VHz;csiBAQgIBn<%Nu?eGH!iB0%}?f6UWaWtRb z8?MBULYy#O+wKijw2)BvtJ~ODmE-3J0K=mMbR-}s0$CXMLV<>>J&lb)iHMXpj5x+Z z9}#1?^VIvw{rIci6%ABfHWNRSpLwTM2qeC+M5FoF2(DgQ`=S5&B0xwVqN~Iqxs! z&Hj!`*|t7^Lu*H)moeBs`iHVs^p8d_b%?l5)#}E4nn9^%p#hmpJe@qpEM96eOn(K% zoD^HiqZKyu)U25$Hiuyw4+2!VP*mB3A|22efyyW>7s)c4lS7x-##0CyfkgKTn^Ed? zIodK4E{i8Rjm_Q3oGWwhZnam6wnfWPq3Y}2K>!Vej_iC+fBpMSqt1@7V`NQ zx|>=9*ZBNR8dZm1BF$e&NG*Y27|#tMCWkP$uf0>yh8hCxUbnB2Qtl>Co3Hg+wz9Qp z;o0uX0>MV+Z)pq)#CGriQ!1|`!N(usu<-l^i<}+)kgwVAZPcVyAYM4cUg)L)bpApq z-69A_N?1OBzVwSa%iCIg;c%~07oP1bZ+4bnyueuw6Fd)w3YzjJ zgo_r#JYl|GB-^~fW^XwjYAeThfL8H`Lx2VY9bo2f1}{8X1}p^S-eAxlK*ApYLr=ri zk4e26oLsG0nzK4V%MKJg3i`{(Qb$5hdK4^}xuc18XZ4ESF@XpZREJ`93>me$=lKYdb^qpdc& zrb9&8tRc|W-sKCTfOn5`~22`CyXAW^3mCOi@*-h>C$Bwe2%8EA45M)(TXV_ zT4c#+N>8w%1tUNRbEuooq3)o^-|R&zH?(>^K><6VqLZg-EY-AGx=|F>8uDF-`qR{n z(FUWMPlwlgLS9Dw!y6Jqk1y=@1cRPyVL@1G!n&{X!j8TEP3`*3<#yB1>&B?-ZbFx4 zo?tWVE&-%&PQXq7*T*AaY{MCqXi$!8f&4g`dkoEU`h^uOzYMlcMX{9SmlckNb@#|b z#z0XR44;G(mrlHXK;m{ufs$49&N!1yB^&XB$2y5;XJ?1lvdOd3%CV%OW)rGwb|z$E zHcxUSe+FF!t5HJj5)gn?rUax0OA?4Gs(2WzNkx_WXK?K@rr1EgDoP7=x(wE=qB_Tc zRjzZaN$1#-iDONgat-b;CLzd=Mwh`FMI>?O_JB>{QVCiiLkpXCkBV=QFoQLyXq^O^ z?8fWwQHhoWo{S|2ICtikf~wun9C@y(wn1uPr}jT;QK#rsn95JlJ(%Ub$bi~W#S|7)9q>&2s7cI)el_BqsAju?zxCqaE7hm zr7}a{r}q~DPq+V71D2c1x>Nd>;-khdCC^0z^2ulO*OX90~MN{gTJRS*uHU-`;`9$&r zA9(BewMD{rOZfW|PLC3h{I}-2I7E$HO8+0%3pmfjZ3pl(>A8#}X~5PMqkc}eyoCG0~SJ|T_&Ba%CQA9kfqNEG~+{qXr6hhzSgcD_Xx^*iXB z>@C$!8YI42S8tH`f0FQaIi5c#;rIqW*N>WyWHaIkwaokr0VlnMFLrSb{5>(mrb+x% z`=>{u2!F*F1ipGcxst;a0fHd&d?(+=5FV@=XzQ*gh+TG-5fcYx`3x-4Cj;1C!^cuZ*Q<}fp?GCrWTNm(q$xYT6 za5uLG>OHOQMmV_PcJAnuzQ3@y5l0HAZVDMVj6ofb1-PqCAb}dM>RI&$( zP^%gn%P+&5+~phKIt;Z3y$x`m2K*J$w+K;N7Jw?`UnSlihu;?fdY>GC4L-Qnk!%e# zFA#XXFy0R5^}5g#x;jKacmTcWP*14M-OibZJe$1kM6%f%hF4jTinrK_NgICwUOTi* z@<=9}kkFBK4(4{BUsHAAO83f(R=C~JM2i2-z2b_CsxDl;JUK`BC*5v%t=%gxkQ^>p zQN!G;)?Qp)wbp&{`RCWJ+~D3&RlRm4aZUDELfEFD*9$c;Z>KNpTD5j{^>X)uiuvcT zcARAdf;wbCA8vgpB%Gy?9d36J>!iy0i&yn8ywrUbb9?zIga)p?q?+Jv;sbXhxCkxk zT-t;1PuF-iF&SyDg*C%*D?Q6#jyL5w7hX%Q8#IQ`uQSoGYu5tV6Am=#`DoI1PqUX? zzB(AjjB^v|59Wr_T$2D**(dfV;)xZ-nFBQ;(C7BzDQC6UjdC z_Kt8U2|3Yf+@*}-Atf~$V$!ZnoF5=p$8 zx{5C&oh3A01LLBuzTv{<(sFs@B&ihjp%W~u5Al@>Jf&6B5YAHG`tr_ zmKFR#h^p$<<#Z}kfrGk=7Eh>!RWx4f2eAmlL6Nh`8>G=8Dd9#Q&VW2bAY<*VVOGKQ zS`qekBF=sJ6~O>E(F$*i9Fyq4DV`D(VjL3`Dh|dt@WcsIa{#<>tKbC)X0UEnf%B0z z41EyRTi?+PIywdcTqODFgvzR~55nAKijE^y9C}ev9B8Si|OTXssoI*Cm%00QuJ#7 zxg2mz)p2_DUe@JOz*{-D#4S~SYmf!saa?}oSA9d$D-W8gzmijhmxG?(sZwd>f5n4$ z{Bnu_kFF-mFTt!C5h_a2D?jZVNw3yBs{GXYZ~cw<)@hU+k6$YNX23`% zBp+SM@4G_+l%7SdkX6Mg+=QP_ul9HQCH*lS8S$c&^wt!5wchO|qsI0Ar6N>!mx{>n zs|fY-mB0B>dYlB8^3#b_y8QIs2GJ}1E5G!!lKy)tLo!hMQ~dBfp(J|czwY!14CN0| z_|mLYlHHd=ul(HY^#bL7GH&fkE&qGSE5J{oseSreZGtEjU!_&p12pp4Dth%^r z{~WZ`)QVpD*FTo@QBp20WnZdXWe5L-JVH_Q$`AiifT+^#MbWG9dEn^u%3uGMq>m62 z?NW3qd>MH>{Ya;zuTzLJOr`%L;8gy+6g)+rx;G(Q zx>R^fi}MV5+ab#*znXp(=?TQiv7ds%F`PkxcwV*$)jbtA7l2e4;eL?@7F=&C#fW4Y z?xcR`tFIRX7B%qoLqA*6r|NITHbL++Wq2v{O6Ga}l+U&c0(zxNzZ9KrWQs2C8&ZoZQTtT$!ANtJ&b&@$0q Put(6-yAAr4l4Sn_3uW)) diff --git a/CodeExamples/Add-With-Transprecision.aarch64.c b/CodeExamples/Add-With-Transprecision.aarch64.c deleted file mode 100644 index dad6e14..0000000 --- a/CodeExamples/Add-With-Transprecision.aarch64.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x72 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x272 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRI_F_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RR_F_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x78810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RI_F_32_1(r0,i0) do /* mv */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_F_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x3d & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RR_F_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x79810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RI_F_64_1(r0,i0) do /* mv */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_FADD_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_FMOV_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_FMOV_RI_F_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_F_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_FMOV_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_FMOV_RI_F_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef float (*pifff)(float, float); -typedef double (*pifdd)(double, double); - -// Simple addition between variables with -// specialization transprecision on data width -// Width depend on the platform. At least 32 & 64 bits. -// Could also be 16 on RISCV or 128 on INTEL - -h2_insn_t * genAdd(h2_insn_t * ptr, int FloatWidth) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - -int main(int argc, char * argv[]) -{ - float in0, in1, resf; - double resd; -#if 0 - long double resD; -#endif - pifff fPtr1; - pifdd fPtr2; - - if (argc < 2) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atof(argv[1]); // Get the users values in1 & in2 - in1 = atof(argv[2]); - fPtr1 = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr2 = h2_malloc (1024); // Allocate memory for 1024 instructions -#if 0 - fPtr1 = genAdd (ptr, 16); // Generate instructions - resf = fPtr1(in0, in1); // Call generated code - printf("(%d) %10.30f + %10.30f = %10.30f\n", 16, in0, in1, resf); -#endif - - fPtr1 = (pifff)genAdd (fPtr1, 32); // Generate instructions - resf = fPtr1(in0, in1); // Call generated code - printf("(%d) %10.30f + %10.30f = %10.30f\n", 32, in0, in1, resf); - - fPtr2 = (pifdd)genAdd (fPtr2, 64); // Generate instructions - resd = fPtr2(in0, in1); // Call generated code - printf("(%d) %10.30lf + %10.30lf = %10.30lf\n", 64, in0, in1, resd); - -#if 0 - fPtr2 = genAdd (ptr, 128); // Generate instructions - resD = fPtr2(in0, in1); // Call generated code - printf("(%d) %10.30Lf + %10.30Lf = %10.30Lf\n", 128, in0, in1, resD); -#endif - - return 0; - -} diff --git a/CodeExamples/Add-With-Transprecision.power b/CodeExamples/Add-With-Transprecision.power deleted file mode 100755 index 75732780162f3482e581ed1471c2617f4e16dfba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78288 zcmeHv3wRvGm2UOSNHelzdHlebr`y;jlB1UmF=MdNNPbDSF~Se<-XuFSl19>iG$Uq4 zFeVa~9kQ5&+_k?o8?8XoShJ~yYe7Q;ji44Yl z|5J}qt2JZE4=vig-BNc|ojP@@&Rxk$S>4Hprray%T6qE+Y-Y|M#}%K1p32suB}Je(}ZOogh26z0f0 z8E}5YdDtEhR24F=jkr=<^^Zlq{;|gSRT!iO;n*)jRgRiR<@~aoUzSs0k8GF!s(&x#C$yqpRT2{Kb5@zQY%%27KIC~u9_FTA$AwQ=FKWrg2S1qzD)EbpsTTHF10WVe_a;( z>MZnGS?G6zuH&>Ggj=R|F3Uo{Gz)!77J6wGIt!;FN!A{Y$76BU-jPhurJ*H+L_88r zHnHY#vOUxsPDJhrv$pnlEE#S{vbIobYpj7Kl8q?Hn(mHAl3^A~#+q0lfPvHyNF+n? zWS}h+i84ylkXp!AuBokF8dy*^|2nWWx5c88ji$I`$e%flOdJ~i>Jh4O{dAfRxNkqqxKCU(B{t`<`%kI=xIAc+8kJ0CLdN?dWA}Z+QVbUG*cwSPeP7 zUv;t?%DdQwSnx_fKAuY2oNi`a}}^zpWvi0$38iV=(Ac7}^Cs%0{+xwzM&m^v zHa@C@ndNWu)#+dCOkR0kXR`3V&WE)7(sj)^=ekIzq4hzJ2e9f=`;8xeWEj=7 zv;?!WhVjP5FwdG`_Yiys(i zOkc!t#au$&@1kArqOA{`<`r}qs!tEf4j6BK^fcO%%CGE9T^8y5wU*ae!73L$bu&ZX z>x*<&xf4dS2H{p}7p0NEwY{*o3n7ma9>NjO4 zsBRi(qVC%}Q?nmH{S!KaEU@UQ+Zb<4qihSptyE7D+g25n^&fE0>ms^g6fZj9F78UL zp3{|DzqIQy*c#$F?JnM^vtr;_TvC8?WzYw9wq^xF;yrEDFYbS(!S~ol!Zr~;-DtbA zM;0BlY&zU2b!cZ>22!)X+?o3Hx49lElOCN?kC~{u1-McAy|t{fRnqSPcJ1u%dsVvz z(5^h$F7R_+=*0VFJ9HrZnwtDenwwUI{<5yNt9^P+SNrLCU3LCdT@%=WVp^s@L;sgKy`D0*`5^hcNPj)+K2qhww(Ylj77TNu%38fdzf9 zNFLQ*)pu(khx%zW?KQU}Ps&q$jBqE#sm}ef&amXUodx=$H2&5v!#J4T^~lG@YHHJR znNNMYW0ZYM$?cRy^Oj=cA7Wu0PP3ECVGBJy3$P5RzN1dblw{`Ue{k!>mXF<&AQO{k4k&;W}Sx@V&FPek?YC+$FHe@c+cvNK^thP^M zjCi+J)a1#rSc`BT#;$5_?ar&ww=|AO7TF$zJE;t}l`=k)8yK9| zJGkC{=wAD?fz}t)eG+Hi5mrm< zM<3~nww*M~aI?KWvI9kIOYb{>7%WS+4C`(c^{)^8`+&?djG*r|8K-(hUl%`su@Sj3 zw-`6E#U(zJqr9T-tNM_}I(0R$+KY9w+eh;1An#cz<0HuXs!1MUf3|Canj1PW!rA-z z4+ix(o3UqJD{qnW_y}Yk1@6b$-w*V%HwOBdF)+Ypo@83(Nsksdd8t;3Ih9xPIOf@h zz?kB@5kJK$ABbR%Jc#(^nuvFE`WxFFn$er9&Fm}G0)1sDFV=;5T}MzJdw3sX-yWdQ zBSWtYXRvSYARbNd@VJY;u$yQe*2mKYEN>^J4TCN6%J?)^yAytznpe4e-mm`OU>woh zq;cv+yB@;&M`NZJW0>@i{qLWEHk$d`B%epC+<8pu*o*SNMj0KtA7fjq-a?#kI0Cw= z^AO@n?m@&AZu=1b4fv-$S-g?v@-9t;%vT&HyEFm#T-hyXuRBCY^N8{YyCY1@RH1_MqUtP5b_r%!WR4?g8 zoNzqgzPjtz!2T^@{~r23wSGDJOxTBh$lCl{QJ2Cnn=G1VBr6wl%AwJm60(%7Az7tT zmg<9SvS^-?tg9jGD#)VoMeTB!+Vy6?XqT9)e2qKFm>+xHS{~Avq4W$nzBI(uSc@R; z!kQ@NFfYT$pbmP0$6*_&+zwXx@D!9m{?6$LcO%@0b%*Q+ zcz1fVEk0dS`{-GGzlFN{P+2|-p85I{iR}7LvupeoDVIw=_J+% zl05*~)KiMOf)tcAHd`%W9OK{b;MwlWdaGlWdaG zlWda0k8Bd@scce4J*7=Llb+W@MmC%Dls0;sbT)cdN|0qjB7VJ%!Sn_E0o`{m`5C zP-^}jG0k7vL#g>odnje6Xb+Wf{tk?;f3Npu+EZM3d!_ago?kWiUgt3Q%%2L>6lSO?&>;H7v-zl)aSE4^imU%DnX0K?svYpvv zl}K3&A!`9-(RyIrOFSfHk?o^B1NI4g?~rLPK|E?NL2sElbU5$NZB(mHgw1?g6xVj$gY6wS0RsN=#Xu_cYEdk zjPBm;X~}24ck72dx|gB-k-C?mwe-C1WxT@f(0t2gZ)yHy+cz-h==Tk@mmcjsTyNp< zd$@6>w_|Md?w>eZZ|Y;!--N*@+28&#>hFPqajy3m^*3G?Iis%v{*X_!zq`jsZ%_W9 z-gIA}d^EIQRz4}Z?^Cvv?)%72lU?19IPIa-eIM;RhV3Iq>61E_`@XZWWBP!r_G9Pz>}ZLUrS^8& zWStttv!mbst7tdv4QZd4P1b0h9eq>EqP^Zo{vP5{{vL`ee~+S*zlY+=-$QZb?>X0J zM|a9+NBi;Y=pddQ_2AjjVLUrJf@j`G@yr`OrIUD0dh+j3m-0otXn9t1(`&*PaTw2P zR9|NDSi_dL}(-Uz^S6^3++_{Ik(p$KFQit@>9zt5JHNSO4xEAN}jYUdF1Y zF88VzM9=Q=p=TZTE@P_aed9w<+N&r%)qJJ?953@VI!5!A_A299@3Jw{TkTa^uvb~~ z^E2;Nu8{f4R%hE25RUXb=_gntp2r&TPq5+EXHz@>Nz|omeKuLgq%7+@Gv;Sg%cU%} zR%DZPD$Bmd{GQ9npNV#ntsiNxLOg1(LUFZMQFPj?P+aX*D6aM@*lYCeIEQCb7hclXG3eU1#BcqCOby-i7Ydtu{eDKOnu; z^Mg-H?`318H{GXO^){~o>OTFG()+$K(mT`Ir|ws&za3Zy&ug!Gp5y#b?&zPBoy|DU zwDxsh$Tk0b^&X@CR%_pGtbJ97&%E}{lKE=PXIo=v-i);NJ@k(kZtbg;vOdK4Jkx#p zXx6@ue=`2oKJ#x6=skCOzdqah&E0GLOLVp>MDLvvAH5Ur#~M4@-yB?swRJi65A@FF zNPd7TB%gV0J&1c;x<4jcyU%ogyccve?sg&mDtO30usz#7v3y=f?-!5t{rv{hT0!^g zs{IE{?SInL{ynn&G*)+v(EjZEfziFAbv8EeLDPMY>Ibs@|5^IsC3*iszE<)psD60P z)DQbj{Xl*r8b{O*yR-F!^ea<8Wb>cw7^C}=Q+WTLY^hlv>W}}d`jp7u6CB1`^DjR> z^IG$a%vW>%eAb#`DNFTrHd)6;ai8^C&-hy(%)ec_5cc~^SWib|zdtYe%=Wuq&bx7S zZ*&&#@Scsm^x>TZnxFLEpVE6=-5ZUO-uT|pFuiHLJ{SKO+0|iwd+E=95qa7C_Gj{E zSB#N8uF2rXA5VJEA0xf#9R=$+H|zb0-wTh?IM3w!p!IjWjPr$K)ZdwWALB{y>&8g$ zaqs)c`Tx}SF-G%S`921)A6@=~Gw(;|%KQtlAAR`yqOJ?EAH7M+`cU4-WZT=Gl6zb0 zZ)MGXe@)7wJ8uVofOh?!vgL&^p*4e_elkKePWQxr?+0DdnjM2yP+dU$^ z1Lbz3%wCjz8^1X|f!`dz&)(=gh2I=s@>65=Es%d0@`2Tma&My?@alUXwx;@0AnA>Pt`#zv1EEHHjddhxDL7t`<78;Ni4h={TngpIzf_QNDHL^fYkX81iR+kL<<;9zoqb zjqK4Mr`VPsH?au5xiSyms;cQ~(jr|=>;ax`(jGuOuamw_l3M+#F8bb36TUZ;TI%lF zu_<^ewSGm{j-dZkYW3VM*ppM#4*o3^;PKjip{pOXcC;-d+eYnGbtB$K<*BT-joqyB zXb|mdMEel$>t-_#H?iAg8*fLuzKr+^oGa0;7tyZ!c^h{yv}^{eof z)W6-gCH3w%wwS-SW*EkG^lh^``5ijc|1Ro(SAAoR{MV*$tfA>l>lPn{lzLRd*FEgJ zhB8m+s`N9AZA{R-o-BKYOs}TN;WoM)Gplqt#D1S} z8IeRX9M}1mOGC*>EUGt!BCTP`7intkNVHt9r$2Ej%N2=?VtoZ?)*E7tVZAvV4ad2R z^rts(3&o?6Xmg3aeq*&Bi6)Zqjs{-IAn%a+ZVk2G9H-Wn>mhtSwFTkbYr;_kcZnb# zZeAOYQ99Jx5w2}(6AfCod?kOpW9GAw^97_Hl^Eh+h|(DSen0T z*|O1;Nb|274Yx`D`q33g%fIQ?QB{!UU%zHl{3|1Oh4lpj+yrnen%h{c&z)aUc1=Z- z{^@jViHfO?Hu1F%G9s!tTbnqmcA4{r9>~2I=YgjTqaUIEw}#=xbbA}&wFrBjHjGUO zAN;OiV4u&9A>57d$oCB6Ai^Xj(ouvjBOE|D@Qh*1z_4HQeZ!#dY`cDF7@tE}_Ya2A zjnMxuhVeMU6R#P@VT8SJ8^#HQHSZWkffL`web+E55Wf9^VQfG+=OpSyxCxeW55gIz z4C4sG{Roeuz4+E6KeT(+F;}WeyR1NC_zobx!HPDb44*pHc~z`Bx9W1xDsVpc9m8lv z$f^tL9@VNQ&RmZ|ICPwKI6c7P5JI-1uv?p4buZ^>801MJ>q+n&qf#phccgh75za*Q z?8X^{fq4lbTUO}jGDJ3`{DU|PfGyRB{0g4GO4LF5q}yWTzfbuq3jL}XF|bhn08TIZ z;&IAfCiMsmmY;#P?LvN#@~dV2b%Xgnk*|Z4 zLVf}I{Gf~H?@wdk)HSMwc=jON3uC*+!+ClJd2$?zrw2TTVVL_TTjfMuisx+NoUu-Wf(oQ z9uARFpVkTQH?SlBj=rZEG=%5d>9*_w&-UNp?JSH_@Emt2a2?O{%5;zqg6DCJaUCIe z2Jv&;!+B_&9z))NKN`jX#MyF;;s24d$F=kk=U+LNKB}!Oq&}-FWGi#4-gy1BW4{t} z!HYWm_+qP<%GigEfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8S zfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8S zfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8S zfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8S zfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8S zfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8SfQ^8S zfQ^8SfQ^8Sz$c7=ArI9IYg&^T^)f7wVRtU`QgotB@7W~ME}3q3i1Y`ijTn)7WI9LY zSGYueu1p`7`4eRN&t#Y{!x=KXNQNqKst9xN_Bdo(mkpmL({34FEW@H4Q9qLHL|P-; z4|zN-*_bLfAlvJa85J_jlc8$gX+!9HRPqB)uD`;uU#7n=^Hn`#7H$!^WRrhb>YXj$ zrk@`IE0-?4UN2g?c4M(VzoKkGnHo1rY6&7@%!-la_lR-1Ofgu(%Q=4;u4*I>Wf1uW zreWs%#k_narlH7J^O)K}hnmM~-U#a8RkSyhE`R)1(cUA2EJI?Vz7H|YMSagnyWy2w z2j%!v=^=%Yn1@s1!>5p6;&Y!2iGME64LG&#pFwXIqqcjr1o#WC#eAl0GG7kOvkIad z4)-@HaJj3&;qbVZP@v_m0nzzc#I>t0zJk~tIZq*QeghY+=<+!fKMfwOc-kF^yIeVu zXp%YarR;grKaIfQ$tg$q91m(*Ptx$m9G6ZFP|?pL$2nuFpW@%7%O%s+Q_xM9OQ*#t z=*Pu1Ysz;K$g|xkC`;I_4_;pGYwG-IRJwq+ISdDfPNYd6*}N3SDowoG*eC zn)y&?-u;NrMr6VQM4Z&fc}O`tu8S$~x~3q=|KG^VEBAhhSZ;*OoXfew1$RK8H}|`q z6qqJXK_d4+&N9T=#7DrD`^BAkZ?`hL^&s?evZ$N!V_E~UA@;JW6JHgT<+F1&tDMR{d93^ zLZ+LM7?&o5x*wqGaFWI@5wAo$3g6;Hx_VC#@oU8SM^2=xSA(*Xdl4%v zKx~qSuHNZ9NX`sX})ilSfV(aE@azln?UMG)Or@)2LqgxXy0nI7u4iQSYjYtnwi z!RA5W{=$?e5TELGznU`{Ku@bA;;{)lelyCtU(26G^dh3aotZtYL$00CZq{UA$VVGRkfXc4K>0o#8@?XG}4g#Kw zKwRs72virNY3$LQsJ)<9W?L=$@4+H1obwoX9KX1DIV8BQ#YI}t98tA0F~YXwwt|69 zH}iPn2)Uh@um-USWSjT}Szkrmf7{vH^qu9rvP=$q}Y)nnaXYNX^7K<#Up4sfFj=OczW_wNLmaDQ_>P-tEOHo8Yu-%GYbTOQU#ei-Q1wlzv`<~aLCxVnSRf@x3d&gJ zC8{SsbqQ7OpYgS7iII4=G{H3kQUsghGWRnolqz-Nk^icChfM-3R6 zJ>`LI8W>=Pzr0Ojju|_vf!8z;*<@`#%3MT^TYO2hPzmOMTe167P@U`sTwU5ng%g>E zgBbB&R#u+aoM;TUC(7GncZcKc4JurSNtH;3;>oi0#EAjuP@6$#57R2HnuTM|?AZ=1 z)!KW=cd}kwGu6-@OGHxT^^s(Pp*|IcTbn4Us_%$`2Z_7NTO-kqLH0;AoGiylp_yMb zH`<_E*hvXh0s_qV6G_|H?B389+E$Tc&!;W9`ZEJ3GQrKq@*Lh}V}l zH<-GHiL6Sr5QOkkz5Yuv;&PioC zTCVd>EvLvir71^qMs42r^xH4g^hGtml5uIYD!{01YjIPIhkCM+dQ2w@}Vv4X`WF)s2+1JWV}QhnB0U zGz9%*TYGsT-ca6*4rnM{PdscLG39~Hqj7k4+kQR;7_*1!=c7N zJlq^fB*Ssa4>X0^BCVU*^46w>*9LBj#T!|)rIBYX475Wkict$XSZgfWtT)Cw>RZEu zwL}ww&NHcg9^sdcXd==a4L9;;L7{~Knw;|&%69vNZk))Xp|&uGXX*U;@?KvrZNqe3 z5($UHBu-QeVl+nMxHObZ#v}C|$uLNiUn&?%=P&T-rOkTj%?tEWjOHcag~-w-guX=> z>6i&9($p4?H-}3@t*xaEu_(GTnoNKik99<0Z<{PZ zHii=oL>0h@-WOfOHR<_@OjWsI<~)uuOiiEtyWVaZ5CX&ghM0Y>?ZlT;dA8orTaAQX>>HbWHFK&W|77z%}> zceR`CUm!p;H-MQMXhNCsJ|638m!9RQ48@xd74wFbL zVVx|rL54ZFues*xM^!Q?$r_8vSUPZ~%PJ-Zs~A>?WVb#)P#cAP((kAC2K%%4ovr27 zV)v3Pua>!Ne(S19Xb21?)7*%-Nb{_R6I%qIy3;msVI61bJMbZNCsWTgOk}L-uJrSb zq4XSfJfr+vrk;Nc<#)48&jpj%gwyaC@-h z8R-+#{@|hfg)9^PPBw{c|E%;}mW*YVa+H20XKH(@vln;avo*kpN{-Y^toB+6`HyQ@8T&1W8|NsdMhRj zm6J`cuX8z*S&?OYev8w+tTixH&NEVek8}LiX?qnp`fef;zrP^-X4qm8c9EFq2ESwQ17Wp zLQYW1Z;D_R!P+F}=cY~e@2ja;@hX(@3a69%bN#E-h@`;O%UnqVH z{e4OAvCuEWeLKnbTj;AL-Dg?P{#4R~7XJG8J@k~zxs9xP7=U0-BrD3T3 zgcE`InT3C@q<35BWi^W^#0=*gSqdGi*|KYZQU3;Gna)9S<} zhyRpd0ox?U&*P*HjvsQmh?}oJ%|hRU38H7P^RIz_vRQzP|6kC(;O~~>S+V?q%ZL40 zA#gq>Ur_iPqSp^!A6=+-N>G&^45xE?0ee!;$3rq}rlhy#OZj~KF;<#I&ML|OvYamm zk*4EM5KeYXVLprfY04t!E-B~1>7w2>((rvT3;)+aCw#2y=C?qf4EwNO;-&`UGg5x* zEkeE@c+s&Fq0VDNFVB%2$8?sm;Qs=bU&z$c4J7%2{ZK}n$$L)YNBMjXNPg^-IQ@uU zw5JEIG&*)*9(mFJBbIviN`B>HTqf9AF3OSoMrkMCmvk@agu@OgM|LBdBl!5#BnF+)Xu$@ z{`vyZfxorh`?(xZ)_i?93w>V}`tJzO`h2GD2b3)82g0*m_DfJ@nEafkyYHd*&bU2J zBs-d#a2p*6EZuPPy1<&+^&0{Kq?VadjbY_23MAVC4RE!D6JTkK1)5u9^`X{4BOD=c zR&=CTL#(a6HJl7L!ns9M_?%LBXQL?&KS!XkqpfYTs%iP!WxS#l>#A;A9#E-4ndDp% zGOHRJOK*$73$q~}iYD6Q;f6>e5{s5`=PH`svH&-&iRj93G#n41Y9chi9|OXM2z*LN zw#J$l2);;io%DR&6iVEYAYwe62oI-*5^aHYE<6#sD;yY1Hiwh&KZv4{rq+%`3khk1 zA1T&gb|qBsWB#JD_SR&e0oi5kad>B%{Qi||YO9w97L?7ujtysm`1Vk9m~PQW;0&iC z$q`uEq@QX8Ht7oBo)Ksgi4NfppqnGnI|6lUHUO$v>s{dt&2H~Vl5fjW(Be!Ou5Bn8 z8wn6dP7Dz{TuRg3@knwcxI_<)AgLXmzL-UeWq-1^>ZaPI7`P^Ngcm6gfIl~|ye1$< zam})ItZc*0OUooc3+e|uA1JoPqQd*c2Y%Z7!W~T*LQU~-7=x4Xel?8|*(MVO-Y~S& zJdOfk?hNEpBG4R;u3rXgDT2nU+K>&=QI^!p&^){_)W;L|Ph0 z>K&Fw;HFyxe9EI01S%?$Hi3);%*V~E2YJ__wdsOY%a(C9>k|ptNSYB$jxkf!=@RRy zd|DGUf5S~nrA3od-dsvf6cZ^uOHH)2@O8^K1S%LSOKfgShUyU}<05QPF&Gs*=VN93 zsa92WZ7KO#%izN)YYD+Pl{IdTqOb^)aglRZI8HWnNFsndcvVAGK*nIYSQ*E)EE!HA z&c|w5JjO>`S-1s*mMlBDaMLMP#%(t$Boof-h4UJo+U6J}h>`#oY_YaBJhcKXT;I_Q z_iQK%!>5w`S%=E1ua9HY$`twURU9CwDA`}hp(GIq>8At6;}4zj-a)$l)+u%*)gMm<~);epvBS`rnCMVyzZzX+IoHDZs)HU4|;yiio-Vap|{2$dBi4QJf;whbGzmNSn(me>6gVlvwyBENLper9|Zw ze##GukRS9KocU1tE80Vdn9D1FDMEf6Qj9XR*8dIA&E=I}6(K+7(BL#3*7Dy$9+g*Y z%Kxf=EDG_#U@C8IKiyB6%PT)^#VE`F5ap?>RQ<}I>zCzwNH`8PK2-gxU4)Oh{48yslJrX*lV)9g^lf%9J(qX8Lax8$Wp$CzrjPV z&kmJr5yu9ylt1PXoX=Y3kF|U*2v!=^_z*cfaWoHhEKgf`>1}7CS@AnnC^(fJWqB*VwJu6q zAQob#3(kYIIO4bpCz(<;{*?Wv-@8~K28FSM^tvOCpR0v~r-oxS8T3r$@Bfr2zd{7E I^zick4@5Nx>i_@% diff --git a/CodeExamples/Add-With-Transprecision.power.c b/CodeExamples/Add-With-Transprecision.power.c deleted file mode 100644 index 591a0e0..0000000 --- a/CodeExamples/Add-With-Transprecision.power.c +++ /dev/null @@ -1,850 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_FMR_RR_F_32_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); -#define P1_FMR_RR_F_64_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define PPC_FADDS_RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); -#define PPC_FADDS__RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDFP_RRR_F_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xa & 0x7ff) >> 0)); } while(0); -#define P1_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); -#define P1_FADD__RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FADDS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FADDS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDFP_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FADD__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_FMR_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_FMR_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef float (*pifff)(float, float); -typedef double (*pifdd)(double, double); - -// Simple addition between variables with -// specialization transprecision on data width -// Width depend on the platform. At least 32 & 64 bits. -// Could also be 16 on RISCV or 128 on INTEL - -h2_insn_t * genAdd(h2_insn_t * ptr, int FloatWidth) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, (FloatWidth), 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - -int main(int argc, char * argv[]) -{ - float in0, in1, resf; - double resd; -#if 0 - long double resD; -#endif - pifff fPtr1; - pifdd fPtr2; - - if (argc < 2) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atof(argv[1]); // Get the users values in1 & in2 - in1 = atof(argv[2]); - fPtr1 = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr2 = h2_malloc (1024); // Allocate memory for 1024 instructions -#if 0 - fPtr1 = genAdd (ptr, 16); // Generate instructions - resf = fPtr1(in0, in1); // Call generated code - printf("(%d) %10.30f + %10.30f = %10.30f\n", 16, in0, in1, resf); -#endif - - fPtr1 = (pifff)genAdd (fPtr1, 32); // Generate instructions - resf = fPtr1(in0, in1); // Call generated code - printf("(%d) %10.30f + %10.30f = %10.30f\n", 32, in0, in1, resf); - - fPtr2 = (pifdd)genAdd (fPtr2, 64); // Generate instructions - resd = fPtr2(in0, in1); // Call generated code - printf("(%d) %10.30lf + %10.30lf = %10.30lf\n", 64, in0, in1, resd); - -#if 0 - fPtr2 = genAdd (ptr, 128); // Generate instructions - resD = fPtr2(in0, in1); // Call generated code - printf("(%d) %10.30Lf + %10.30Lf = %10.30Lf\n", 128, in0, in1, resD); -#endif - - return 0; - -} diff --git a/CodeExamples/Add-With-Transprecision.riscv b/CodeExamples/Add-With-Transprecision.riscv deleted file mode 100755 index 538deae5730628be5c5148b3df8a70f1b1e899eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29136 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32F_FMV_S_RR_F_32_1(r3,r1) do /* MV */ { riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32D_FMV_D_RR_F_64_1(r3,r1) do /* MV */ { riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32F_FADD_S_RRR_F_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32D_FADD_D_RRR_F_64_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FADD_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32D_FADD_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef float (*pifff)(float, float); -typedef double (*pifdd)(double, double); - -// Simple addition between variables with -// specialization transprecision on data width -// Width depend on the platform. At least 32 & 64 bits. -// Could also be 16 on RISCV or 128 on INTEL - -h2_insn_t * genAdd(h2_insn_t * ptr, int FloatWidth) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, (FloatWidth), 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x31F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - -int main(int argc, char * argv[]) -{ - float in0, in1, resf; - double resd; -#if 0 - long double resD; -#endif - pifff fPtr1; - pifdd fPtr2; - - if (argc < 2) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atof(argv[1]); // Get the users values in1 & in2 - in1 = atof(argv[2]); - fPtr1 = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr2 = h2_malloc (1024); // Allocate memory for 1024 instructions -#if 0 - fPtr1 = genAdd (ptr, 16); // Generate instructions - resf = fPtr1(in0, in1); // Call generated code - printf("(%d) %10.30f + %10.30f = %10.30f\n", 16, in0, in1, resf); -#endif - - fPtr1 = (pifff)genAdd (fPtr1, 32); // Generate instructions - resf = fPtr1(in0, in1); // Call generated code - printf("(%d) %10.30f + %10.30f = %10.30f\n", 32, in0, in1, resf); - - fPtr2 = (pifdd)genAdd (fPtr2, 64); // Generate instructions - resd = fPtr2(in0, in1); // Call generated code - printf("(%d) %10.30lf + %10.30lf = %10.30lf\n", 64, in0, in1, resd); - -#if 0 - fPtr2 = genAdd (ptr, 128); // Generate instructions - resD = fPtr2(in0, in1); // Call generated code - printf("(%d) %10.30Lf + %10.30Lf = %10.30Lf\n", 128, in0, in1, resD); -#endif - - return 0; - -} diff --git a/CodeExamples/Array-Ld-flt.aarch64 b/CodeExamples/Array-Ld-flt.aarch64 deleted file mode 100755 index 5fe4e94f5bb0ff172c5cb8f0347f11781a5523ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48048 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

uG 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 u;P&BG_M_TmDxM@21HxGM -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RR_F_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x78810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RI_F_32_1(r0,i0) do /* mv */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_F_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x3d & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RR_F_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x79810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RI_F_64_1(r0,i0) do /* mv */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_F_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x5e2 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_F_32_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x5e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_F_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_F_64_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x3f5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_F_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_FMOV_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_FMOV_RI_F_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_F_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_FMOV_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_FMOV_RI_F_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef float (*pifii)(float *, int); -typedef double (*pifsi)(double *, int); - -/* C compilette prototype */ -h2_insn_t * genLoad(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 2 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t tmp = {H2REGISTER, 'f', 1, (wordSize), 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0103, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = aarch64_genR_3(tmp0002, tmp0001, immValueZero); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0002, immValueZero); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%4f ", ARRAY[i]); \ - } \ - printf ("\n"); - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resultOK; - float res32; - double res64; - pifii fPtr32; - pifsi fPtr64; - - - float f32[] = {0, 1, 2.2, 3.33, 4.444, 5.5555, 6.66666, 7.777777}; - double f64[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - resultOK = 0; - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) genLoad (ptr, 32); // Generate instructions - res32 = fPtr32(f32, in0); // Call generated code - if (f32[in0] != res32) - resultOK ++; - PRINTARRAY ("32 bits : ", f32, sizeof(f32) / sizeof (float)); - printf ("res (32) f32[%d] = %f\n", in0, res32); - - /* ptr = h2_malloc (1024); // Allocate memory for 1024 instructions */ - /* fPtr64 = (pifsi) genLoad (ptr, 64); // Generate instructions */ - /* res64 = fPtr64(f64, in0); // Call generated code */ - /* if (f64[in0] != res64) */ - /* resultOK ++; */ - /* PRINTARRAY ("64 bits : ", f64, sizeof(f64) / sizeof (double)); */ - /* printf ("res (64) f64[%d] = %f\n", in0, res64); */ - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-Ld-flt.power b/CodeExamples/Array-Ld-flt.power deleted file mode 100755 index 5a08772e1a8a83f11023bab6f73fb9c9cc7bf1ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78424 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 B6PN%1 diff --git a/CodeExamples/Array-Ld-flt.power.c b/CodeExamples/Array-Ld-flt.power.c deleted file mode 100644 index 4c1794b..0000000 --- a/CodeExamples/Array-Ld-flt.power.c +++ /dev/null @@ -1,895 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_FMR_RR_F_32_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); -#define P1_FMR_RR_F_64_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_LFS_RRI_F_32_1(r0,r1,i0) do /* r */ { power_G32(((0x30 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LFS_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_FMR_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_FMR_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef float (*pifii)(float *, int); -typedef double (*pifsi)(double *, int); - -/* C compilette prototype */ -h2_insn_t * genLoad(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 2 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t tmp = {H2REGISTER, 'f', 1, (wordSize), 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x381F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = power_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = power_genR_3(tmp0002, tmp0001, immValueZero); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%4f ", ARRAY[i]); \ - } \ - printf ("\n"); - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resultOK; - float res32; - double res64; - pifii fPtr32; - pifsi fPtr64; - - - float f32[] = {0, 1, 2.2, 3.33, 4.444, 5.5555, 6.66666, 7.777777}; - double f64[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - resultOK = 0; - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) genLoad (ptr, 32); // Generate instructions - res32 = fPtr32(f32, in0); // Call generated code - if (f32[in0] != res32) - resultOK ++; - PRINTARRAY ("32 bits : ", f32, sizeof(f32) / sizeof (float)); - printf ("res (32) f32[%d] = %f\n", in0, res32); - - /* ptr = h2_malloc (1024); // Allocate memory for 1024 instructions */ - /* fPtr64 = (pifsi) genLoad (ptr, 64); // Generate instructions */ - /* res64 = fPtr64(f64, in0); // Call generated code */ - /* if (f64[in0] != res64) */ - /* resultOK ++; */ - /* PRINTARRAY ("64 bits : ", f64, sizeof(f64) / sizeof (double)); */ - /* printf ("res (64) f64[%d] = %f\n", in0, res64); */ - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-Ld-flt.riscv b/CodeExamples/Array-Ld-flt.riscv deleted file mode 100755 index 5b8138b4212996bfb589bcd8d76b8f9fb034ace8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33296 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�g$aVmgGaXuh1T>K}Zi2H!r<4@tQp^P6Fv;bK_ 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 diff --git a/CodeExamples/Array-Ld-flt.riscv.c b/CodeExamples/Array-Ld-flt.riscv.c deleted file mode 100644 index db41554..0000000 --- a/CodeExamples/Array-Ld-flt.riscv.c +++ /dev/null @@ -1,815 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32F_FLW_RRI_F_32_1(r2,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r2 & 0x1f) << 7)|((0x7 & 0x7f) >> 0)); } while(0); -#define RV64D_FLW_RRI_F_64_1(r2,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x3 & 0x7) << 12)|((r2 & 0x1f) << 7)|((0x7 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32F_FMV_S_RR_F_32_1(r3,r1) do /* MV */ { riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32D_FMV_D_RR_F_64_1(r3,r1) do /* MV */ { riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32F_FLW_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV64D_FLW_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef float (*pifii)(float *, int); -typedef double (*pifsi)(double *, int); - -/* C compilette prototype */ -h2_insn_t * genLoad(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 2 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t tmp = {H2REGISTER, 'f', 1, (wordSize), 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'f', 1, (wordSize), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF1F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); - tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = riscv_genR_3(tmp0002, tmp0001, immValueZero); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%4f ", ARRAY[i]); \ - } \ - printf ("\n"); - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resultOK; - float res32; - double res64; - pifii fPtr32; - pifsi fPtr64; - - - float f32[] = {0, 1, 2.2, 3.33, 4.444, 5.5555, 6.66666, 7.777777}; - double f64[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - resultOK = 0; - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) genLoad (ptr, 32); // Generate instructions - res32 = fPtr32(f32, in0); // Call generated code - if (f32[in0] != res32) - resultOK ++; - PRINTARRAY ("32 bits : ", f32, sizeof(f32) / sizeof (float)); - printf ("res (32) f32[%d] = %f\n", in0, res32); - - /* ptr = h2_malloc (1024); // Allocate memory for 1024 instructions */ - /* fPtr64 = (pifsi) genLoad (ptr, 64); // Generate instructions */ - /* res64 = fPtr64(f64, in0); // Call generated code */ - /* if (f64[in0] != res64) */ - /* resultOK ++; */ - /* PRINTARRAY ("64 bits : ", f64, sizeof(f64) / sizeof (double)); */ - /* printf ("res (64) f64[%d] = %f\n", in0, res64); */ - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-Ld.aarch64 b/CodeExamples/Array-Ld.aarch64 deleted file mode 100755 index a2a38992e0f9dbf96b355f1b03984d06fd75b0c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43952 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 B-tGVZ diff --git a/CodeExamples/Array-Ld.aarch64.c b/CodeExamples/Array-Ld.aarch64.c deleted file mode 100644 index af9e00a..0000000 --- a/CodeExamples/Array-Ld.aarch64.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef int (*pifii)(int *, int); -typedef short (*pifsi)(short *, int); -typedef char (*pifci)(char *, int); - -/* C compilette prototype */ -h2_insn_t * genAdd(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 2 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, (wordSize), 0, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, (wordSize), 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = aarch64_genR_3(tmp0002, tmp0001, immValueZero); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0002, immValueZero); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%4d ", ARRAY[i]); \ - } \ - printf ("\n"); - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK; - pifii fPtr32; - pifsi fPtr16; - pifci fPtr8; - - int a32[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; - short a16[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; - char a8[] = {0, 1, 10, 100, 127, 127, 100, 10, 1, 0}; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - resultOK = 0; - printf ("Size of 10 INTs %ld, SHORTs %ld, CHARs %ld \n", sizeof (a32), sizeof (a16), sizeof (a8)); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) genAdd (ptr, 32); // Generate instructions - res = fPtr32(a32, in0); // Call generated code - if (a32[in0] != res) - resultOK ++; - PRINTARRAY ("32 bits : ", a32, sizeof(a32) / sizeof (int)); - printf ("res (32) a32[%d] = %d\n", in0, res); - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr16 = (pifsi) genAdd (ptr, 16); // Generate instructions - res = fPtr16(a16, in0); // Call generated code - PRINTARRAY ("16 bits : ", a16, sizeof(a16) / sizeof (short)); - if (a16[in0] != res) - resultOK ++; - printf ("res (16) a16[%d] = %d\n", in0, res); - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr8 = (pifci) genAdd (ptr, 8); // Generate instructions - res = fPtr8(a8, in0); // Call generated code - if (a8[in0] != res) - resultOK ++; - PRINTARRAY ("8 bits : ", a8, sizeof(a8) / sizeof (char)); - printf ("res (8) a8[%d] = %d\n", in0, res); - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-Ld.power b/CodeExamples/Array-Ld.power deleted file mode 100755 index 406a0507411ffcf3551cb197a8c1b4ebde81eb83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78192 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 MPp_hykEAI3|N55}kN^Mx diff --git a/CodeExamples/Array-Ld.power.c b/CodeExamples/Array-Ld.power.c deleted file mode 100644 index 11e0390..0000000 --- a/CodeExamples/Array-Ld.power.c +++ /dev/null @@ -1,882 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef int (*pifii)(int *, int); -typedef short (*pifsi)(short *, int); -typedef char (*pifci)(char *, int); - -/* C compilette prototype */ -h2_insn_t * genAdd(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 2 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, (wordSize), 3, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, (wordSize), 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x781F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = power_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = power_genR_3(tmp0002, tmp0001, immValueZero); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%4d ", ARRAY[i]); \ - } \ - printf ("\n"); - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK; - pifii fPtr32; - pifsi fPtr16; - pifci fPtr8; - - int a32[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; - short a16[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; - char a8[] = {0, 1, 10, 100, 127, 127, 100, 10, 1, 0}; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - resultOK = 0; - printf ("Size of 10 INTs %ld, SHORTs %ld, CHARs %ld \n", sizeof (a32), sizeof (a16), sizeof (a8)); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) genAdd (ptr, 32); // Generate instructions - res = fPtr32(a32, in0); // Call generated code - if (a32[in0] != res) - resultOK ++; - PRINTARRAY ("32 bits : ", a32, sizeof(a32) / sizeof (int)); - printf ("res (32) a32[%d] = %d\n", in0, res); - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr16 = (pifsi) genAdd (ptr, 16); // Generate instructions - res = fPtr16(a16, in0); // Call generated code - PRINTARRAY ("16 bits : ", a16, sizeof(a16) / sizeof (short)); - if (a16[in0] != res) - resultOK ++; - printf ("res (16) a16[%d] = %d\n", in0, res); - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr8 = (pifci) genAdd (ptr, 8); // Generate instructions - res = fPtr8(a8, in0); // Call generated code - if (a8[in0] != res) - resultOK ++; - PRINTARRAY ("8 bits : ", a8, sizeof(a8) / sizeof (char)); - printf ("res (8) a8[%d] = %d\n", in0, res); - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-Ld.riscv b/CodeExamples/Array-Ld.riscv deleted file mode 100755 index 6785e5c7406b813e93dffc28b3461b6e4e53cd62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33248 zcmeHw3s@9Kwtx3@!=MmE(U|8tGSCn%j*3|~=AnRt$i}EqlWhKX^Nk1t@+~iCFq`Bi z8+8WJyfjNTYC@th1dZ`Q)TlAWpiV@ML1NGlmnc4>#uy>mfGCgu?^JisjHoDH@AuvN zeKu5AovL%H&N+3e`c!pK_sj94M({k(X@`zG#}Sm{!*ll|p8O)m`5?ZZGjLtG2+qib zaJ~$tJi_6*7!XhpkxxND$OW8>dMShera)!Lrt%!yL?qN>yc%oegrgjkLK|bz76S3X z1u1oi7Sxx`v+!4-6(JB`RIZ~4CNpL0|0c$DMr zc$8pX#84bbK2^7X)fI0D%sF1j6w{=!!rG)j_%= zy%3#t=#e0p%87S_Q!Gf;2JO340x;; zK9^?A%}GkL+S6aKaye6T?Ocx4X3Ms5*5}f5DI5EtyH_SzKn0Ej!nm40Kz1R&FXVSpQp6Gp5=nThf!0k|$d^A|gW=%q5IUj2mu= zHVwMplNkg@RG^uJ<3$AOUCUUmcf@nCyv;wQs%+lMy&O(v-J` z!8-0AREQ%qhv$4${7UV?WJ&FJ9zY(OUvI_eJNc2>7{UBJ9u=-rR8s|x)d&7slh`cmgV=3 z=eS^>pPOdHkL7}=@NLsa@CjXKEf}VoJ8ufd6-@6NK4Ti<{4LXi5t98HxdLc$dRcJZ zmgzI{XH27#0;J!2z2Jwin3n0A|CN`w;Ok3qV!Ma99A(pI`fi_n;+bK22}bAdGgrri zm}B`F)3&UCeoDxG?hd1=sM#oqtpgW1!dfcdHvKUcLsiTL8=9xi`FmtOACbs_k$bIoi5AodU zu^~(^UfNWpFh*217v%G^z*)=uZA!}7Ql+NME%VEiJh7#!jOP^XqQ|y#e#p-c24%qT zvBP^N{3YSFZ57+zDq~oz@3cN3yu#rml`&Lo{o_)SGVj&Aqm(~?IB}gfV$Hk;?wL6( zXB*`_qV#jVq6=W?NkV~SO*mS2qM02gPd{nag1Tl=?XH$JPc_Em zy{c(-L9NybSlmh;Hwi!djHb(@s8{uj_ zI@hm_;<&u&@ddqoI6lD<=4>_1oIYZWwTv@D!~5oteS+^6;^e`+&8mI2w=|hZC5m|ZbAblNd*45H9N7VwWjd1TBu{lpbo4tlC%U@8&?8p%|(F|P+7-fFtuGB;mhaK+ z6H{iEE&jTA+paC64^8WW5!qmxy?XXK=lqzwgyi5xKVeB14yivh`U+)C~EJIkX=cwE#eip0( zcr(^Bcy1X%mF(Q|_yFFJheZY3%B5^UlVum^IEDBM>4Hq7Y072Jr&=@qz=q z8U5t*g=S-XN@b;U|R8roOnN(T{4}a)Ri09xaUdvbJz!@Vo?my}pirY0i2*7xT;< zl<@^`H*)LqyK(h%0HgJSxBt%Nr4{7s&)3iSaZd2@KM9T{{3``B6FB3d?_P<{pU?Wk z5z&PcBG9K{=+iLtsnmscNQpdJ=Z%Yc^XOB4R@v^dx!+WNGk*`inCvqlKkPvowQK~x zQd@WEpTyzp6M$zXyxy1Q!kPK6J0KS<8xlDn3Dr4x*2oF%>+dk!LWDZj1!8z zCd_BH8I0bjVyTy&n*R+(RO99tllgsfVB&?R({WXKX3EU%i(SQAca@GlIL!|u>cUEA z^z3!B3uC7LI)5ZApjRW8`S7y*!X2a|Z@YNne#I`_mVR%eUzM5l{*DuV^Udh{o{fHm zF*}bE=9IP$XI=daNF7ag#4VX2v$W!`O`JF;@* z{85+pdHiBGhj+U<+^%xigE;)MmN@*VmilwWuVjmz=I%yNxqb`w*ktWN*yP1)%$FB^6q~&0Ws{UgmWVvnCNHWs zd2wBgWPaQ1n|Su=B-rHBQ)cd8Tv@z#S4DaGH1fO7D>kWG5Ufgow6LW-2JQ3ED$Pb-|)|;-ud6PQRH>opy6PxLq*i7G~&h$-H-wY{sUtxMT ziYjM48bxa7U$yWc12AKvwa(2?*5z(_s8&TvsudEjT3=IZUD^e94+%elgdah|V$6D& zYlJ1UuQ2PqUIbfGMl>WJQ^ju&XWFa{$9oUNd1 z0rf&J&xl6;CG+@oj^n258OKwWxySLHZoXV9UqLjES1`UlqY=z~N!ObW#_<(6yV4lG zF3yxOtp8_iUH_HdV|dJp&Wz#gk4dYY9mCy(!B5U-ixF zAG_`9?#2M-zx8ems2+Lv1l9`Yujad9gon!KiC?3yd>&8)L7a}fxR$5Li*rP{>IL#n z!V=+`%*JfA6SGklcqW*Q$UEu4D-$A|@cdlo9q|4H$qdiW3C|C+3A{hh{SI%g4&GcH zytz7fb7$erodrK<;m!RHZ|)pvM`Iw9?hhng(>GNkt4Fr4S%R(nJ@QRYa!&mr$CvPX{4hB^BVjzHe>hyCrWOH53c)f_~7-OyT&QAW!YP` zHI{#S&6YJUAGrSc&+Ylt^x02ZxxV?&?fKMvwfEXHvwOCzIke}xW*cR;toNEN>($v3 zdFpIgug;eB4#Sop0kfkcG&V@Mj}K~n`tc6Eaj)xl&7rebynfeMes6dE?oHRp4-%4Z z-qjncn#D)z&Or>OEGzT5@gs^^B22A71~+@{Ey}7s2ZPNB#V(uRXo3 zy=~i-t^MV#?X3MKtv~;D(6&;YhIq=ZD9+icgDh2VK?v! zvv9}j&zdn8u7B?K%*M41|I>CkWs2_)A^W87|NPzPJ=~qN{)Er!TsPb8UEHgB7qqt* z3Xe=;UfBhB7#HAST!4ph0Uky(^Dcbl3-B%?{e%N_nuy1%y&oOkI*U*d#-Hln;$%H z9#5+)WrxqRo9Ef#A-v1>cXU^{vRv2d>t4^5r3dkeD@(b`C+2gK_`4H@FC#a!ruxcP zo;?TJU3p;pYG3X=;mdYDu_pqbhV6WQPM!^RA{6_7>3a7zo3Ce2WVXkiu!2^3*roDt zJMr-4Q2`@>?Uk`zB-+_raQ#=f>*7MOld^@iHT~cBwv#dMUAxD<>|??8Tb0L7y1flM zX}-ozKr{Ssx?9lf<(pF;?M5O`_05}A-@N(k*hv%iPKbNDFRX;`9#XE{!}Xq@`lbcz z|L!|~8;{k!tJTKt&j$1S0_=IDV$UNrSme`i-B^VAdl9Y*&A2Kwik@A(#*hA~4y0 ziwwF5S!Q&Rvds2dh~_M4&VmMax)4kV2GE6wzyzJ2e3o%`mT?;;p9P&sCYn0XU_S-H zgkS(&2tufMmeF;U>p&MJ*D*SiTn9RXd{zi|ePCR4_!XZ7@-Ygm5Rc;HpDQ z3qUs?bn`(sA9U}4?j6v*gT0vr@H^gx-|?QhH&fHc0l7~@?$eO_4CFooxz9lEGpI?C zI#50hsST>sA@Z4>WXGhdQ=mBwn$w^;4Vu%SISpMBzDYjCbjC625cxFIS*Uy(eIyZ7 zs)MDRhRzn;hz6X$31P0^9AV-aK{B6lNX|3p^)v9$YQe)*buC1=eig#R)7UpUElAGO z4#{;I`$oSx!p*;dZXq=HJ~a2f(d2p`np*_TErP6zpt*(6+ft-q(23XDzfY3Q_w^xX#(~l$)~=h(LppPL30u`CqZ)(G$%oG5*j@T{1Evh z)0`+1BoPGa2>B#57fH}G9c=#OjcQIjC4`wzIl`Q$1j%*EA&I{V;pSg4f_?=r9ca#c z5;k`dHg{5x#9the`4`ySFR-~^K-VeF?b!zDk3;(7pga!gk3;(7kp4I{s>tpuABXG_ z@^L16qGNb5Zg!HlF~Bp;3GM zMm6U=4x2mf2op~TlKF%~a-M+Aoq)|zFLt0g*D)bX{24a)vmiNtc1W(DVROeF;bxM* zQ=02v0*WJ${s^Q$0_l%H`eTs(7&NNL-c>#V*`wqmOm>reWFL)P(pU{>YCuy1nj@e& z0-7VxDB(xSHR=pk1IR=WG-r^HKyx8#U7?6?aI}g?VRJ`eb4LZqb<}}ggv}juggdD> zJJ6i@Fl_FyBg}PJ0G|%Yd_)L$9)Zmr>8$4FVD1$ULi&S{z6R3QK>8X;UxS(y*#qT+ zklmol9wOKLNMn~YRt=hipg9PdgP=JGnuE|N;hW@Yb)F+AL_Wwg7b+iQ^W4GT$%+r& zsNS51gfQ13SX_-DnQI)9vj!Gd1B*M{vEE!i!Qu|W;tmRu^Pod=9fZXlg2f%`tlqlK zhV0dly&AGtL-uOaPz~9up-)9}om>scLrD*?8A-1GiDV|41E4tonggIY0Gb1!IRJeg zV46Ch&T<4vG9XY#$OqUgci=GD@PQlEn^+BdtA@Q*3zDnaA&Ec1-hP6;{nWAE%m-j^ z2Vidp1WEk2Lo)vx_V#bs+rK-hx0;3Zki81BSAnt$vR6U&D#%_1eJYas%2kj&Lat(x zN6J-9W}?{-n*E^J51Rd;*$lNl1XloD}N@LNnd+GvlldbK~o8uO3+k7pM)PN z?^S2Gy?{&vL2m}RlFe|HTgZYdZ&YvMKG@qn*xNoqa_w`V2VrmfVQ1!Ug~+4n;By^wt`YEmQ*lq(>)L6tm2-uny5 zO!_JZO$BHwKvMyl3eZ$QpM-Cc%hmafpb)u&=`B>QVDnqWr)0quH>x-1cd)nbU~hW` z$-LJgIrqZe_QKx2?^tiHJ+QY5*jt4lIV&8Js{;1+9qjG9&g!kt7m&RivX?{la>!ne z8px+W9QIZYdn*?tSGhwH_rTt8FU+~8W4)Po!`^no-gXO;_^m@Se+zs2 z7WVdSXZ5yl31r^|*>{0*7i8ZB*>^$qUC<{<94hZ(^83oW07Vc4`6K0B;PQju9~xut zeRbo!*YjatRLc(3vIDj3KrK5^%MR4C3mPU`N#4O~@{@M}iX;d%MaetZjJKn}&y4%Q z2w~0!NY((!a6j0L`@v3n>bns&Uv)(!L||t(3_H7FVzVHbn;nv~S-{Q%EU*Q19jw5d zyFj-Kbl-sP8_<0NIy`HN{_k+ayLJd+;!a1Hd8Z&bcRD23P9a=`PRyjotIm{Ido08n z-+}Dr79q@u=h9s*&{->V z)+&TM*)zo*%if``uR7Z?{*~3|0(A{lG3;GO0`?BnCy(F6u8+A9Pdrr2`3M|rhdpeE zJ#2?PY==GUFoqz6iev>5@^)quUFGe7q6mUbnB?uS2?H#|&vjOaKnN4hLD%P?>vPcc zIp|tO8?=MbfnGY)X9qSRmI-0zGDn!ROpsh<4p_AiZpPD@PO|RK=%r@N0!YvV37Q}Q z?n9U_K!OX9-~uGTeF*c#jwR?&@~cV!E2F&ut#@j^TH;7>p7rh>*E#B)Rj<}o?3s?< zaiMoy=p7e&XFGalJ9=k3Mzhj40kR8yW0GC0Zw&Hw>>Gs0)T3KLvlTQh(6~V30*wn2 z5q^}smGx|(ycLi^r4Er@=-E($O3BA`(aeca|1~W5Ygq8tu;A^m;O(&B?T&EQcGPxN zIj_3kaMeD-7~3Xf76}4=IMitpPCVL2J0#+R=Z^gcWB$LKUK~oBvQqYuwrW7=#&}b>sRVmY)P9`W+ z1_WwJE`{bI2%1LoZ>gd=*A`gTR#?_nL2_<&NUp80EbPRZx7}>biKRlAxfG+KRFGVy z4oTc1gqycuRBY+2=Gsm``puAjGo;@P>dlaTGo;@Pjc#VLi}Gg3F3Er(dxX3h{&1vB zG@C%P2{fBPvk5etK(h%NCHzo%6QlN(Hvx(u2-K1CCTK2-pctB4HmNqZ88){WHn&-j z#IGEZ`778Q?z_0Yy4jj@Zi3Big3Wy?NaimclJiU0+?TL9lD$(lXCW_mBd9h)`i+o& zBc$I5={G^6itK*!M#vs1Z)CDZ$s4h6V3LVu186pYW&>z8fMz3THbSF>A0cmGn(HcW z02D#dFJN<DNK}b&!4oq~8GPH$bC`>;dvR$ZnF?G1(3B2J9Pz z$fU8gpjiu=b)Z=XnsuOA2M!27N?yw}7bvdk*vw9o00}w(WTFAZ@ zvadxgYoSj?a*jzJLVAGBgvx8NZy?E}uhpPg4Vu-USq+-ipji!lu4bBA&Ge>|2?~_~ zfm)JRvsrF6*3gm2Q|xUG>}@UVZLJ_V*E%HETG-oXu(!`{w%)|mu(#E)x7C8=TJ4a; zHL$leu(vgx)!SDKAbSa9FM;f|+gAeFOCWm*^jX3r7v&O2F3Er(d4ycTWG0%Gpjio; zm7rM(nw6kg34IcNsJxO<`^qZ;MGyq)NO>ij<5psxG$Bv1w-VS}3GA&zki<_NlKE5E z+o!O%Pj9x~oGW2(D`9V|1j)S0AvssU-d4fhNb*jN(_u3q`*Kh%hwRHC`*O&>9I~&3 zJ{8IRKEQdY`KSEx{^ww2g1}KUk=*=WA zV>8@x>>GrjM#bKi!`@cF-c|^bbA>~4t$@9)guPLp+}!!?6WH4)u(wYH$@Pf?lEdDX z!`?`mPU&qG-IZGk*_T50rI39YWM2l^mqDM3jl8c$%0_9>r29-KQUdraTrPw!+kf+$&$FR4LVQ(J`XwxB?m%-ka z!QPhLY`r;`z}}X?-j)iId8tEkE`_}vcTl8e~jxcADAi0VhlK2tq?IYM5t}=RF=^nce*8@x zYv#p5m~%0#bFm^^vnbOy4UqV zZE1h_gsu;U=HbcZR6Mzyisv2DW=xwp#kVZvYmWUE*NCUp_TkQS*$QDL?oNN0z&V!Y z<1Td>H|x>ekIo%aIcEO&>hVT{>!L9voLh@0=UjMlt`bij9BW4Z z;P=%9`3WVj4X+sfRzg)m;iE=r?Rg`95o?UZvv5(z&SS1Pzh2)p1$V-OF!Il@&rj)E zkl)w{+Vkkso_JCY`!aa)W!DLge(9ONxVB`N{L&M(C5Ny&cQ(GMFB}dnm9*g=b5S!m zY5jP_<0A@urs){=hqWb^x?mqJrna;eo>@_Ife)t>u#-_+vG6dS|A~~Fv697e6K1xz z@nGJJd5{EqIOjer+YpiPCrmNUAP-O;h7ca6P!BRaZ0T)eU|B)uG9w8 z=qI%$FYm*g*V+q`h^-pFM~;QxQ$FON_aq<%Ihs{{?(ya_VL9|!fi_zg9G#xfeG&b# ze`8FfIT6nSDende8<@<64Tw%LJZKnaO*4eq@$QeX6ue6X@6$j=x*e|=F|Ze!B;}@O zXBkqH(le|mPiHSJdC=f~rwQ;Ql+61KBN&n)IXlH_NV8^HZH$(^RphB8TUL5jT9je@ z6LE(0EPJkPYBH}@a zncz7-fqOD`6gM_3xBuKiKhYMyiR8f!LR3)zkP*b~>R*o`~xTD5W> z9>!lA*JY#so5S9Y$frCA` z3}@hA;0zq>jq`w^9nJ&y84QM`2fT5p4SFpNF#vPrPU4+2LE#*?XeQ6a#C7AQy*;1f z4%g!?Hau`rP#zS1Qb<9X=lHvYhpIqx7s6jQwzbtEo`INN4^)Ww4#cI1qYzgk9*g)O z;uOR^zi4Zlg*XLq3F4?tZEaPEZHSu@&qr*)yKn-&Y-<~dcmm=K#A^}HMf~T@ZEYJ6 zPexpWc;gnd2i`}!&<^4rJ5WF3k>9qpl_DNo(bjezarxf1wgGro&)WTMZIclnsA_8~ zL@fRYJj558+S*Pd*4_goyfBXAU*!3_Z_}~7J0Ro4&)eGQy-S=P@6JLLh43u$NDp*S zUJSyE$O}bGhXH}!<@6fz?m^7O1qQ{<(v6tTkJ=KqBQB7#i0(NACvYGVI}A9#hG0Y9 zV9JRL91u5)j|=eQGIj*$1`s8+QG!5pV-*~Oc{)E!M_9Tz)E}TT0Fm&hzm@}Uhk`f2 zgSV04QH2I7Lm!MnUyV@l)HZbwtBn#)C~&fXBPlqLhw=4Spaf}rjRZ~(aB>wKFTPUU zd{JF^tr52gcq0`&O-9{NulC*oP7QD-w!?W+#Uc4N0Ouaq)Y~eKN4{BZ`3SEDc&`AD z^g*q2Lwh?!N={4+Z*>i$xZKs zivis`u+6uqBjWNds1&;AfZtHs*5*>$%V|%yOldBsJzWXtX2A9b)BC34 z0_W<+wc|6;XNwtnnyWMKG<)%R5_HpcwzZwP3ZIo%;nP54YIj@P{HxIY<0^E20o~i> zZEeRD`ARO+=Wa#75-)uYfJk$JZ^qb_l=fmqYT~g@2vS;$VOn8h$p9MC;o!=)wn(I* z6N74>6QKqJ^-~10X})_HI1L5>=D@lDR772DMp}ojr#$j(;MEyx$t+i8}o`a4Cv29JA-uuq^%%I}P+i8zh z^z)&uXwgsqAVs3jKtw?z+TDbN&m0iz?h2j=Odks}ggb&`Dg7}{!ks-y5FaO{@9Igr z`#%4Plh~)n7DU|x#9zcNfgti*MZEti27Zfd&hKl2PAib;mxva`-xSD?>+uPJXGGyg zV0NJm%l|+HU5QfxOp1#Di9zDKh=LyiYL`C*y@fJwAL&|HVycLv3 zC*69=^QAoMIi60sZzwN>^7c_4opgtA^8W>SLHfo>;^7ByqsJ=*keES7OJe_p?k>8WH`tQ;E@_uh1;kS=a{dlEHzY|n{ z7hb8;?{$K@@_}0ri++a*)1U7ZO11j!q_O~|><&&Cf%FK&eM4MQYV0P>R%{dz?~>DfOR}T1P1>rFKy&n^FfU z^*p7{Qp!Oo>PsDs7$3TEqW=T4WdAqNim2~H9pqaMTz%he^NMf#U|e1>$dApId9 z8E`-)PKUd)6Ee(wDx6xf79VQN4 z496!_OQ@W0muL8)v_Gzq=6y_y(ZZZ-jpdq99Iq0a2ItfK-Zv%G(`> zP?cYTKoyBT0(}>S8v+!X1T&FlgW_JATd~g3h0mkPXa5qFy<|UEM$b5G` zsCRe1M>iqx?!d4>+$QIACQb+(c4uNQ%7(E#L{;(KIRCz4VlayT#8D(jED}RGfB&KW z_^t!zb35oB^nb{Ih(96t-sS~9fGes#7#R;^V)j!@dY=j9TF1n8zZaXs?$qJ-T2FW5DoL;2N)3>VYPeklb3^_8!M!3bW%gEEQE~3@u67ph zPxW$8wl}LfZycp*!Na|%D42VLIu4$Ti7Mdvi-DLnaS+5Z`oLOofkV*oeRSP)F-Y<3 zgim?UWltE$3w#$H#|t`k=DYYIt>kEDv0aXaNmKzUEvS$}x7+yc5dK_Z9>OJ0y~*Z{q4`&Q>;1m{>-iE&p!8J8qf95&dKdRWvVqRH$AI=Ze~t@ zyDhnY8hzZQAHL}FC+}pkeJXwC#}GT-5N*1D0H=I1hKtWg9TaVOD%+OA*|U@XmXwlW zv!vUzy@0GFTMoVlGZp>-FmpM3de&fkOeXv9=~<~>cvG`fq=AD8X>ztL7q|S8a@U&k zoI-0)&d#w~($QdgmL)YQGd<&ZE^Bg%O)1R*A!?#VrgG!P$3JcvKHf57RBVD}^cc&y z`0*2B$4#(|8EqLmE7%%S@V-{)qB9CIIR7q<;1sYw{z}0|pKm7(H+hA=r{9Kf=7$%%s$mWW_zjS@BH` z{n8Bm#zY(X*>h7KNz0mws{5rPeqczy^elYz$qF#jYD=^B!$URwlC$vyOi~t}jp&zZ z%buE*f=6S}0v>hgmztH0I+BwA)=&LvP_|9UOwP{C#Dh4f26+AO5u&VY0Amy5an8-K z_shgnHyMwlXQk(+CuQ`rK4(p4-T8vmmd#~ZNHz8sJpF>+L~e@Jo=mxl`V>1-x}T+) zQlZ0?q}(LcfZSTV#FA1nI7?i1b_S>R1lgNrW!CI050FHblsnmGO-ixYtr@A{A@}(l zYeyaZSYpDs*a`8Mn$>gBe`M0RZBrQuXr6MYd9CNw@idyu*==NlqB)!0I>nM~$GAyK zvs>_-il_7eBw-Gg+@v%Q=lG73CXzd0Ng_T-iJT>I48|||(K6MJ=cN8un^#AcbVcjC zig|T%u4_MMa@w2;UH8kv7qU#r9B^{7?di|;rw4}!(qgg|uL`DS0S7biv-qwWKB(qK z!$8aJk3g|EzA{N?<>Y2uIzub@?2ON`DIaIUsO_Jgm7Fm(#j4cKk%`((lff`LI2Qvt zH_HRjG)y2kq)gT9)uc5SiF7K44sj-{V>#)$kQNHaO;7G;v*Np90Izh=xAf=`*vcBu z5xHS@p=SFJN;zCPId-3Rh) zHMk4Qr#%6soOU;qHMau8H=+YBAsvGHbvpW^rL z6F6#axI4?&_8J8CH92I_gElw>_9ZZ7Uqyjw^^a$i+~vyd%S1PPJ1d{;hH3Z3a|j%{ zSe`>*yFuQt_H>kzC$L>2?{fB3lsiM63DJ>}HiB*7}d%>nt-tBXvmP4j$R~b{fajtv?X3T0Rl*D}W^xeirZ|ullC}F7krs0RD>` z?!|oo_^)0t?ck98QBU)*KYCVcw;#{Ft=7L4@T4w0(K42_WLiEabU;s`e zKP`~8@kYCeGGNXAdDwpoU~PQSmmz~NC5#0>bnw_!q-Tpl!4G-7J<$F@z@_T=?SZ^l zz~0|loB+7St2~aT6tzAB$YAIjQwh~K4e;Ioo}*{N2&TpRQWZZ4{qqiB?{7CQ z2ds_1Anb;&0j!Nrg0}(I+6zK^dkG&8U7kTq^&djKyD$1rg=rfi%9rQHs`51eei85v z6&8tq)gDORo`8?v%X9Rs7S-1m@mUxdx&8zX0376n9|PE%pT_`aK%Wy;{HFm=gS

pMV|MroaB4T6Jts!^<$woxwRZ-v_qQ>r;c2i>dKQrIy8({z!j}M3 z{d5GO{%F8sy~;-b?h(&(^!ymnKMHs>_8#aNI)a}Doa3dRWWW=>=%)gveQ-Lu>o8w? zIRaiD7=1|7l+A@c_ut(z&d7$>nU;g=@s+N=$+ld3?$p#&T!>Swc*2}L0&mI9v?OCi zVYS02Ov%>1!I_eqZG+Q1^*Ii{R8EF9*P4P|?ki$gQqi0x$!1G>-hx%3?RhTM24CEg zGBq>vd60NPSYoB;UV<7+Wc@~^n3#tG&L&3#$)1&*cvg_Do9-tK6RStkvQHS+h^#)1}!qJbBM5pfA@dIZvgh z#-k1?1#>Y?4D9}c#&1!{c?6a#e?$4zT z(mu!PopssQSUrXJD|aL;_yqzU-nV#x<40NOgR61l$E*A+A8z%KqSVS3MHb6=bL@mz zOI&K-nCoR#+w_wLvpVbm+_sdaqXcx!GV3=Chi&5BJ)0jnwYY|G@NtQ0Jim0r7~vP%~< zuw7q%3^!SOeLnl2$Znk_{%SLbR=+rJ*J*N!jQh z8=Kd!=X5ua=qiBAhWh<*<=f#Jt#XCnI3qIX-YDUbUpyZL2BftEmlJmU5ocQM5Z(sh zkzYnWkg@_I-%1H|XRrbHPzjH%n~?Y`lI`(m%bHd!_(fZ+&q zi6uO`4;%&HU8J>xaOrpyf$rfF9<9H20FPD^TDz1_;V%eu&zI7)E;|Oi0Z4nd3lQH# zR(Oa*OzSne8{tHn>Z4T<@keWk3sthL*Q3@uG%J0`-Pq=b5C?b5EjH{Kmd__>2NIDo5_-PI27|D|%=Vy(~%FQOe@ zGX_k;74T?%N!gmb!*R1g``$URNM#g;wZj{k1v#idJv2Ou+1OC?=hFfl6IfqF@d(s! lK?t<70{yv<`Ok9Pbgfg7t5r=qAl`U);?~I+t -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef int (*pifii)(int *, int); -typedef short (*pifsi)(short *, int); -typedef char (*pifci)(char *, int); - -/* C compilette prototype */ -h2_insn_t * genAdd(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 2 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, (wordSize), 10, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, (wordSize), 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, (wordSize), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF3F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); - tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = riscv_genR_3(tmp0002, tmp0001, immValueZero); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%4d ", ARRAY[i]); \ - } \ - printf ("\n"); - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK; - pifii fPtr32; - pifsi fPtr16; - pifci fPtr8; - - int a32[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; - short a16[] = {0, 1, 10, 100, 1000, 10000, 1000, 100, 10, 1}; - char a8[] = {0, 1, 10, 100, 127, 127, 100, 10, 1, 0}; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - resultOK = 0; - printf ("Size of 10 INTs %ld, SHORTs %ld, CHARs %ld \n", sizeof (a32), sizeof (a16), sizeof (a8)); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) genAdd (ptr, 32); // Generate instructions - res = fPtr32(a32, in0); // Call generated code - if (a32[in0] != res) - resultOK ++; - PRINTARRAY ("32 bits : ", a32, sizeof(a32) / sizeof (int)); - printf ("res (32) a32[%d] = %d\n", in0, res); - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr16 = (pifsi) genAdd (ptr, 16); // Generate instructions - res = fPtr16(a16, in0); // Call generated code - PRINTARRAY ("16 bits : ", a16, sizeof(a16) / sizeof (short)); - if (a16[in0] != res) - resultOK ++; - printf ("res (16) a16[%d] = %d\n", in0, res); - - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr8 = (pifci) genAdd (ptr, 8); // Generate instructions - res = fPtr8(a8, in0); // Call generated code - if (a8[in0] != res) - resultOK ++; - PRINTARRAY ("8 bits : ", a8, sizeof(a8) / sizeof (char)); - printf ("res (8) a8[%d] = %d\n", in0, res); - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-Mult-Specialization.aarch64 b/CodeExamples/Array-Mult-Specialization.aarch64 deleted file mode 100755 index 5f29e67b077e9bbe10576173bf02cfc097a84fde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48416 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_GE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include -#include - -typedef int (*pifi)(int *); -pifi genMulArray(pifi ptr, int b, int len) -{ - /* Code Generation of 12 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t l = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0701, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - l = aarch64_genMV_3(l, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((len))}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, l); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0002 = aarch64_genMUL_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0003 = aarch64_genADD_3(tmp0003, a, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = aarch64_genMUL_3(tmp0004, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0005 = aarch64_genADD_3(tmp0005, a, tmp0004); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = aarch64_genR_3(tmp0006, tmp0005, immValueZero); - tmp0007 = aarch64_genMUL_3(tmp0007, tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); - aarch64_genW_3(tmp0003, tmp0007, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -void printArray(int * array, int len) -{ - printf ("Array values (%d) : ", len); - for (int i = 0; i < len; i++) - printf ("%d ", array[i]); - printf ("\n"); -} - -void mulArray(int * array, int len, int value) -{ - for (int i = 0; i < len; i++) - array[i] = array[i] * value; -} - -int main(int argc, char * argv[]) -{ - int arrayLen, mulValue, i, resultOK; - pifi fPtr; - int *array1, *array2; - clock_t startC, stopC, startHg, stopHg; - - if (argc < 3) - { - printf("Give 2 values (array len & mult. coefficient )\n"); - exit(-1); - } - arrayLen = atoi (argv[1]); // Get the - mulValue = atoi (argv[2]); - array1 = calloc (arrayLen, sizeof (int)); - array2 = calloc (arrayLen, sizeof (int)); - for (i = 0; i < arrayLen; i++) - { - array1[i] = random () % 100; - array2[i] = array1[i]; - } - printArray (array1, arrayLen); - printf("// Multiply an array with a constant value\n"); - printf("// Array len = %d constant value %d\n", arrayLen, mulValue); - // Allocate memory for 1024 instructions, generate kernel - fPtr = genMulArray ((pifi) h2_malloc (1024), mulValue, arrayLen); - startHg = clock(); - fPtr(array1); // Call generated code - stopHg = clock(); - printArray (array1, arrayLen); - resultOK = 0; - startC = clock(); - mulArray (array2, arrayLen, mulValue); - stopC = clock(); - printf ("C version %ld Hg version %ld\n\n", stopC - startC, stopHg - startHg); - for (int i = 0; i < arrayLen; i++) - { - if (array2[i] != array1[i]) - { - printf("Erreur multiplication!\n"); - resultOK = -1; - break; - } - } - return resultOK; -} diff --git a/CodeExamples/Array-Mult-Specialization.power b/CodeExamples/Array-Mult-Specialization.power deleted file mode 100755 index 077f0dbdab2d6e9d6c958470df624c5e5e285a5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78720 zcmeHw4}4VBmH&M+lVn2vF#HiwQ62&|q4@_QohZm8fF%4g6;S;B>`sPcl1!P*jFSlt zHj#m)TiDXy!j|pEE>_yAi@WMC?b6?3SAR`iwu`RarCYY8T~xGgH>uRpR=Yvbx8HOB z%)CrylE9BtexJ{K@ZP!i+;h)8=iGD8z3;x4H``aNxx=PuOdU3M6{DOdpScLG_KCZLbjVu>=2gl(epsL5=pk%F}Q;;z`Ak}jdLjgHG@*GYQXr`c&kYJ81 zlYrAB&Eejy0;?e7+K4O3s(&EL^$#>ouV9=6!f{+eRgc7@dLCKNBkL*HCk0bb=|{TJ zxkl;-$lFs;M;RSDzY1DPHvC7dnd%+7UlaiHdJ4WH&`d$1rQ?&RM{RY_wxjv5*IQr_31>Mg*cTQ zNG1>E8^lN1KM!f@cjA?gvj8XAx(H`6PNG#Ol4Cxu1?A+%;pD_C6P|3G3BL+>(kuPg z1VkqKWm)i_%7PDP!GA0Zz9I|$^T6vk(+{#^COJQu1+QnpPtJnBH4C2k)xFx<3-MWTUFtc5lCg2=K~e=Oo_^>+jw^t1LzG#v9c#aO#2>xeaj z3u}2G8i@IsFBT3kuNPk0x(S~QT_`Cr;mz@~%7iz^3%3bRV@(|%6JEtODyuW$X*{ZhwQhcXsJ)IB()l?MFsvpUUe-DX$u(+%rmf<0$2>QOZk3DR+-j9v`J#AEmru zl=8$V<S#fl!dk1`k`Wz#8P*2zfE_`ULCcnVR5075R%8<%s zBG@3=s7}RC<$HE)cK7VKv6@XUg%9mqOL$je=Ky16Wt1nsB;O_9d>!qQzs!OklRxUi z{I9k#Gyk3L2K^7aVmIvSiWTqb`ZH};vaRWt+!pCHv_0st2eUWHy@upIXMFd4!>CLYoj-SO3P zy5sAYb$=DHjA%a0E8VEGQrNMytPu4opbz4I-5r2L`=POUao^ib?wa>S>?8XmAiIip zX*y`xbhuyY5MkQ~sVJ%;va&f?oT%hN)(24iUZsnzvdyX81845l7Bk8=CGO7&#a{Mgsu`(f0xO= zqIQoX_UR~l`)<}H#+AU$kvIp&l^IWbh}M~gFO&E}6W%k*SR-A2Aax;Gj#3=vGSyc1 zpp6Dw;@1tE3(xiN@y;4CrpG*Xm5mf%@@GA%w_ZI5{nduP2X4q%B!5(OY^;7jV~l8b zRMq86U#th52j5ll*6+UweM^2syeRen?x#9DR?75DmS1wf*x@0c?T60}{8wsRALe>{ zpnLtphC$%=&8*A3U5 z?9h;pmjJ@|b^z{RbrUde?DUXK-^-h~jqDd+UC+l0*&;38 zv25{9*`f;Z&dnah=_TCG|oJ_k5wYbWZ?dVK>Iv1Z^qC zSAJO+A9H&3Uf7yp4mu#=K?xs&pHRJhZ0W<3Q3vJwrvdf=7F{q_liZ-)@6@)tbxqAj zvv}M>+XHBO0BsNKWsmkBz&v)4z1II2GZOcgv$|iPpJm^9-h;2u_#%Sx>2-V$XY!`G$nRy=oJX#tN0)j(WE{%(##7Sapi~d+C6Kc?}CRq6Sr zNzYTjD?MLETItz`H0epUJc4vaJ-bHN^H%UE*(CHFs&8rcGg_(dNZ#ewyDBH8x9VTl z5rZG8eyh=YNAI~;kNAlx}aq{Cf zTT1VKj6oW|9_W4AG=5J2ug32&q}BL6inNMTPa&Og{0@$-e{XeV8o!r++{QI=uTY11 z^!~Rque)fTjidaNvRvs-^T3C=hwlB=s%q??;hv**$x)=wvZZ^DE1Ezys)#5rbQO)>L4!&<_LwFLPd z&8akB()gov57HOVH#7(DMS6x@ZzMSWwcR$@B^P!n#vE6H`r;mQUiS%Zi$iY4o*cx! zquVK=OTy{w$$dnlp$s%U?O-qV5YEX4c)pP3@29+BFz7GRQ(=c*#F?LR{(OyyaW!=P zQ2$%8&gjQFgY;1Aj0tJ$j9HS-iFL+lsUwZwpQ8@NEgHXXAWe3l@vGXT@vHdK_*HhJ z@k@R_EN;2Q_$9y17PrWDCz!Y|7&`xsZTym*PGRhvVKWE%VUKex`+6gSc%}3`2bq<= z6sMKGwBAtq(t1PbOY05NSFJZP>MP?kjje3@k}a~WHyYU3*Bck3w~AY*FlL_}7&&e| zEX$P*vc(6oBgLAZ!}f2$_HUyf(&N_m`$b#IhS_-0I3r%U7*jTl#?OTinuW7T`4SV+Eb zDg9k_5wY-M`nxXg%GP`SIO*Mhd+l^TH}^O0=f~XN<1xN>jgy~m!o7C7-gJ+m#`j0< z=ZnUvzZ-GyeI@JtiE+}q4Qu3)^tOG(ets-x>}$M>iEFgBP1iediGDsFKK zb)IW-zw+wHYuo2#xmv?yTSJl^X$|>3tRY^&8seWZho!G=fBlMRORa&j@j9Jloov1* ze_ZlXYp86zE@W9JoA1f*mAuGzMqAqwjau7MTCHsrp4PUMR%=^ItF z&9SX*t0mnPzqYlFPfW-(_gztI+i}u6)7*DOt#!sp?<;=p%N-v-zvAbJ_e(nSel+btjo1F{Nc+*Wcbjd0_D2`7hCKlv9P7SxqiJ9IjMSU%QR#XA8{k9t zsPw#Ftu^U+zZx&SNUME#dVY~{FJ{Kr_Tk5S|6RqaHpHv>KO8w;O_JqG=WJ`@Z0l?D z^RpHID%w&u%f>6)`r5o!KmP;4>vHTvKP`EYuZ$M2h(@i|DXrG(3V)^ULx1bk*w*S_ zkaXs?I*kRj4^3l1?Mu>F_%^p$X&H?L?>eQ0|Aa4BP<7j2Jq z-+6k5eMs|u`^D@_WzGm#u#fT^arBHtjnqJ?S3g zvgw()GW2XP?K6&xp1ZCLJu}@~neQn->hT&Hr}3KU-s(!yyJDR5R%?|WtW`ey(#UHS zzbsdCQnvNQb7R<7eE3DtmYUPD@yfRDF|SqDN?tT4(sSZ$yt1u(%=?O(fN(%t9NVbC|-^2-IWCD@5UbU zKI}2~K(0e0Jf}Xx-x=Gy_&EIW-G3a}AOB63E4{PzJLyaN++TtWe+n5$pY(n1e94Ps z9j)JqM)fl6n;Q! zRPvRlOl#Cbz^iz00BIV}!QP{0F7{ z6hronBL6QSf9Cb(*v16Kh_SAr&*FW|^nURCf7B0U@_o`ljOkg&Mjq3eELT32ZA_Cr zMtgR3%imwVIcDGm!HfEBwD_RnKmDBmrB!@T_{%jfnEzf#$9y3EPJ#X=Z1~?TB-VMB z=xmjbWFk7y_j~YMYpj1KbgA>sBbZO=Z$kcG=N%O*5}xs$cS?TUlN{LrenJ&xR~)=hkaM2ry9>!RR50Cc&2^Wk@TkirT4j2|6cUGC7&l; z>bx~|ocwwdo?YiQd~jss`;S*-x$^OB_sHZg zbdNmJ-!4s(yxv1>q%~tUUKb>PZ7Dpj zo)K+bYWy`nyV@^#(fAoH&Jm4@bCgzbPT?=tzTy+|+mf`uc>e|Q?W_j-(C?vbvZuc5 zcAs5*%WSWmx$d^HbNjG&(sSobd<#XdJ|w?Ma~RK^0^(aW57XWX?FZ_B2LbJZZa?Aa z+ci}0DOvA`gyz$DBl!RwcPV&4g`JkNh zISE({Jm@%|(}2Y1O~?a%0d_}0OG`gRWJxE$EK;`DPQ#PfhDChM{WPQ-_`ff?@ zk+4p}23dcxtdH{j9<;w))(0K0zd_R9Ct$oin;^$$z>UI~v%*eB~hCF`S{+wX|1 z4?14|n52JM!jlr7mi3Rz`Y7l1PssY9OX`0{>aYCaT+$x&ouM168|+@h0{W(e`2Lj~ z^AEp{HBtP!Ph(uM#$NF~F3|Mh`wH}pg#=E$dg9=0U(q*=)&GW5@n<%ZzuBa}*@Ry* zK<;-o>37I;zXPOkP2Yi=Y7^u8O}5=V9cjYhTe9LicQ)*c+OU^o^A5a;??s)(_oCim zuk~NR_o8ZkW~^QdIY?ghJ*6|SS2f4!)ib0lb0jR2aG{h9-t%DEhyq#U3V;~3C^@-{#>z8kgyw!RN` zM*V@HP3YgowDS>Gb3V>yoli*rAUl}-1vbLpsndR~cfhSdRt>UhkQMvj&;P(!y#c)4 z+ROnDbgk3yy%8-tZ_Ft}c<%%69`HT{-W$OCKJab^@1SNR%Ky_?9mF>i%-@m2y-v+4 zv_Uo+fPK_>iI~PqLfU6H^d|d60BO9$qU_Fj6jD7>=UDM$mB?j{t6x zG4DAU^NvB*!;rNXvVzY*-w3i|4jCfrVaVDGS&u^2W03V_$a)g8o`$`DfOj!4XAHCV zw?R+-c<<9fmt#`)mnA$Y;c2N0%DFDbr7oc3x|{$cdxIWvVY~Ynba)v$AU|+=1RWsL z5FL&|2h3#yC!s_7n3|6<)Be|~adXBrZq7+L2hl#+{0tzCn>VGL{m9cib5@qW14we7 zft>x26ZHoMN04)*xRM^P=VKmfw2v)bKk`>(_tbnfh&f^p$LZA|!nj9oNwbNPPkN{r#|`nZG%PyHHLs`~qUQ!~UKALi=m|Q|;az@%1bDcRkPl z#8~~olSAb@2l)noqk7~wzkJPD{gWXy^}M|^a=p-xzQp&as#7x1Izz9XE_Kl*ERnDZ zGEx7boa;72>IOQl+Z;gB4fG?JH?bo4O33RKni}~qc$UHd2E<&b-QijD6 zE|+i(c#%vf=Q6paOrYa3c>qZ!(2r>EI+T-43n9~D$g~_Xtufhq58l-$J4xG_`mO%_ zM)<_gwOA>>jaART9hq92rTmD#f!bi--v3$DYp{zkzR!N~-y&7-fkp7Xhxo>Jepg(s zH6CQdS9}ZmDDH`GIi&81b^eWKED-B9gQofF(rppu9iZp!HvauoQRf8eXtGWtz9&oH z;|0XGq2Ytb(|11mu&kqRG5;jVd-QKH(|zPO3V$Qn{4O&4feku5xPau=bQ%L<5Pa^M){{?Ide3+?>#K`P~)ph zxH7VUuN&VCO{L;9@J0aZn65#c`1$3OmeUGy6X;`b9?SQ@{syNkxWVZ5yR6~1YLT2MO4|G!e&GMc%9>sgVWo2g}Gidnlu2eyG zl2gjj$iAqdDr3Yihdo;RgslxeNxwx=(BIJb`R=Lzqp|y>QHap}`GKA1Se*Df*_Htv zzp3%EVXQum^BB%PoX_Drit`B0UYt+iJdE=(oQH58#My)M08XW++Uxr&^!p|J2BI|L z-ah$_>~wo2+Qd%_9oiybV^BbiiC+PlJHLt4VRNe%H0!tOcllfOxgGf7ow>~%&2#}6 z3IZK5e^lo`mgI{C!XdrI7YO<#U7#h{+0k~Zp8QoMS+7JCl)YE!J9n*E$rE?itl_X>Zu70sxN>e&<=kfRpUae#XZ^<7u}GAnUo#eR zmZHDw;^^0I98&{H{$pdGlBc%jBIUXJ;^=Evt{6*&r2I9@mtPe9vb7Ckp|6QXecOa@ zbm%2>n@i#RFu4tSOpx}-_jCj3iv}Yy_B)aN_{Qx zfk<$h?hC;uiTwlQm_CrgqkW*`u1KwLdLaVwT%x1dp;W+dKU}77^+!8sw9O4R>vgT> z>;zD(h(`ULQ7#kO4m9ymH4DEL_T#TdmQ48Z*R|{Hx1B?K*W)}$zrKL*<@_@Kx&iQI zz-GY12sFC^V~-fdVZdX6#{rLi#W4B-?|alRoCp`s0hR!sL2#-AT!3=hfmjT~- z!!XWK{yz<4ssr`jH4Hc4!rvLjeSl{Gy8zjHhH(h65AY=5Cd^E89omC;F-N>c zyRJ}U_&pW;Ru(2!&_<}RHou0|=GM$WvI=Jmfi}qT#SM>YHAOSmqY@4sX9LbYlph0R zcN8bINi`2~nx+&@3`LEw?`f)aNAbQSjV-{5sGT01)BgfG0QY@DnEtu9hARA<#!Z&lo(-E9!<(u<9kQ)K-!@Wtt!%#` zRqjUlUX;%fIy5N$pOO4G0lyDEv4QHF+Fyxs9VomL!H%JPjgy!6C2e5Ou~92Ta}efxLvv8E6iE*D#(EGN<~@etoj72GGoT3BHUr(N;6&RO)k#o?o>=FA{Y|9?iRu+>VHWag!xizo7 z`pW5l7vuX))OiziTvW$8EDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl` zuqU|GPjfMo&80+t0V3s@Gg zEMQr{vVdg)%L0}KEDKl`uq zU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uq3dR~(STO}-% zP|ss7N*2j{Tf4|RWIkdO`FB4w!h||5^Et9S;SlAyGT$%DC&>JlB`lC|x`bCrsDNE1 zn2pP0lle9&_*9wClkjQ@_vMK8k&O_lP|6Q}JTJ+Zs@Ev#owA@x!h8vpd>rnH+vk?tCUUS%A0wpwaqs{!!Aw3(32@8<0laTX}vpF4C6L2{u0~Gua zW%-q^&l1V);F&XnD_pn*3|+b3bjCqcG#Q!PBRR{FW<`&HD)(Cxx`_!ZZUEpdeE|vH zQW2ZzB&>@tlV+f5aSu`xopg15jgT=yKFyJIb^R?NkAiRU3mi#T*UN-FNyr~_Bwbyv z<5IYRWXt=FvjT-h{{flu-jTAs3rya-6MqZ>Tah2MdB2FT-}1(QFG%ZxltbAFM?K1Ub3CV1vCV&l*R)4V;@T#i;uUFFE*j^Z~s zlCG|^g#2@&{4b8At4o8jlQ6}y;zFb*I_c_~#*@^Ou30?!2qnvS@|%?W1W*1WC2M)| zG$q&aBpKPYi6=>0R})VjreugGpQq$Dp8Quz?&8V+q~xFQUta(`%6IP z-M~G*um!C-@@6`z+lmrYFl%Bj(japJU>keUv+w7t@$!MIlsmu5eBPC@k6u2F^PQo&=SP6?XvS z|1S_dtC-o@v{gj1(oT#V`F6x25fCYSI@ls&CIZ@7(9H#M15mclA){Sga4Yip_M>V= zBLb7-W?%7D#J}KLggmXc#*+J6bR7m&NIk{kI^I5zc-ZG`1gH zy#gE@3vrQAG)FY8LX3zlxj_)nna7;YC?Jm$6V@O#fnpQCpy&%oJDp#|Rff-k7fHSH zi9VnTehbmGN}ewKE#Vur#-K2gnmV+DMXwUoa!rYT1U2c<4(^5U#V2{`G-??seiXmW zakEK~WjL4MET;a}mRAw(&v5<;&WS%Ex_ew6r2hlw>o{HK_PSMuezQCqv8*F=V-Dvwfh^8tYBp|!0AFa@-xr=1i{Uuz?snMYJfWVPs z?mBG}V)G_PVO&`I+UBr=g4>bBAezSP#kUsRR#06~KLxC0 z38v+oi6BBWpQ05MfFP&3Km$Quk)TJmeu^9APRW2H(2bf_KZOV<%wqLZDnU@N(A2`x zYv4;$AR6b1Mv1gY^5ilQ&*Ga<7v?1iDB=19&rg~HPK&`|a*~6TYRc6@NXc-jnIQ}) zRgk6A%mVG!3T(7$Pq&bnX6ZFVVo#aIA>>0Pn0jMwW<#S3@Uu~RvWES|h)rv?Iq;XmG~G28V0wXoMzAlW2sKI&XW!Y#fg zRIC_tgQwf>4}i6^+i-Pg?-v&_4F?h8e?>)Q$F`1Uf25-_5`MrRjWj8^2!pC4=8MKE z))OTh(54oH_CBUn-8c)!oY}K&n5wn6QEq4bxMpf067C4ZD>nyX9SrR$=nu9~RyE%l z0u3@-D}#YhXNo)!^2aK15;W5*aYK<9qFroT#NScTMv`{Knz2$W#~A_wBUvIkQy4Uj zB7~ieaMKoFb8}P@BIl1GjgSza${69k&4KbzIOeZtA{)el)Ck>F&&FwIG)E277_jme3FsbNlSbTG3Ym=$#gZ^^f3+1h$&Ps6uRT&611v{JljKO-au2K=! zZT6En$w_iZ9yJ}9G%0CoM{9>BhYl^C15mlv7Y-k_6eHJ0n^YVXlIvZ`%udE z>K4jgs=@5a=;}twUYW#>)S;DXC=IcGtUXfM5pAk$MF%vMFQ~ZrW^=Nsqm$tdRUK1RBYtn78T7HXsNdJ@jrv;y9Wj5D%DpYV_CRnOTM=wow9tD`INHoYZOy!B zkv9Uas74ZWvS2vWsyBx_HwXQxRze*D&kL!2p5T|xP)DFOU%Q{1XW9Ju@*ZC=Z^v+567c)|#7;B}WGGC2T<(j-qJhnwF+WgLUM>jA=Pz*U z<*j=8oeT7Gc=Hm_f@OINpt~BLj*);WE$#kjtH0bA43;;AL+H*>tOM9+xHE)!(~72J zZA1l7?vF-8VPw!S2%EN)N1_NJO|ftkNW_rx_HeU5xP%5#z!xm{$Nf#L!zb+uC6jh& zYV!$`Kj@E!S;$LDcRZM~CCm(Lv%jN>u);8+_eB@+G}(~YH~V5f+3m>&hV*}Pka=sv z;UEGSXGP|g0n+OahtLv**%U6m;1=!=$vzkEhuVap+DfNX9Upmz?AV(Zn8Rxl?FI$< z(Hrx%rs@Sk(%;r`SCe9;%6%jZ8G?E1@AUGJ@9pgHH`5#z3pABS;Sx;<$|DX^8Fa~g z12L~J8ue`hE6jmV^Fcop@`tuY%<<3brIG8!NcFa$&Xw+u4fV?|(kp$@R=6gVN1r5B zCF?MhYz5L}DSxPWRP$0?H6M4%jKpmdY&+pKA$yac#dFa6PW4wMzV^X z;SNjMEr~<|+Z-&B5nq(t{~bzS%rZSUu(OHm(EW0!!c@Ty)PZOw{3ND-psD-yWDPr; z%&Ictr!Y@O{8Yw_Onm5R(eURV*j{0~GvcpiJsI(IpE&%mGu&ilIPC1&3|O-Bby@JV zOF#S&%lAxp+Qu1v*xAfsNE+%6_G=@(pb!Y$uqFLmmjtx&lZk#B$}{2TX2DkhkDI_@ z{d+sd5AR>vgt0XivVEp~e4yAmi9eTy_ep%?grR=*0Pq@1^&{y|#~O_H8(|`x`)b6P?{;MSZ zOd9@P+3p3G;L|Ai)9yO8dmlDP2sHHj4m@M#Wp4kR`COc4_O!!@#-|%?#q{R0* z1%Ikf#}6f*rTNeAB>qeq{q?vX$DRsnOvA60_`$S(Y?Sy!8vP$h{GqhC`qvykd|W&y z=~)_|*Cbv~liz{O0g|&Xjen`cA4=o14tR|XkDvEQdOeN)GZODf!+%BM&!n~c_Z&Z5 zuOD&z@OfbXc#WRSr9Gei6{jCQPq{D3io3`d;Me_!`HHwE6nYEcj!R&tVxij>$^&#FXs0YsFB#PD^~SP|7Lw{RPLH zTNLR$*p2w;*9rQgprd0N$BVT2S_1qe+hpcWi>tR}p!9 z!Lx?8E6Ue)24m&xBmO3AECn9K)<-y0!MBwmeA@!tu6Kl1`a}Mx4~-L|2|H0hYzSaC z4cTD0b%CG@#O{)NertUlTRI3C^>_G(V|^X%-Uw&j;oIu>rn0U67WWA(=50c8MI?%SsTPlC<(m51W!?o9^FP6c6M=oi*XpOuiBTy1 z@jz@8l6JX6Hwu~D1mSx^&?FEVLhnUK2SQuC4Qn>QRN>%Oe+IE5oiWSj?9*72FqZv%}(I}iE*yRil)x*2|-gPx=>z8Fv8^fV#%P1Uu zv2b7%lBh4#9Bv;%G{i1qx6bRuzPWcromY&Sy5)DViVb%ztB`Un*qm}T^jUj2BzF1u zKuhj&@eMsVY)jPd$53EG1CvW~w=(6WLChF>q~>k)hiYrQ*u9S-LPX6@?e+6LSw23A zZ2cPV%`BN)yOFZoC?=k=Z%i0ITJG|1P1USjxdQD;eCv8dv*iAr$#u;vl%VT3)}l>m zWfOsnbRzyp=QI^3WxfZs%>&a!gGh)CXt|%tqe<&}f2^MN5>eC<_O_vK@t`1W|Camo z5H`sk;`@-vrq|x><)I7BQ+J^S8QUn>Aq?KRI%S}{%yzC>z8qPvcXLOFl#WI=lOx5{ zbh4@SR6nVLFfDRXnr{t*gQ$tV09m-b9giu2^Kb5K#eTdmgm|yA{Na`=+Ppc60U&eqz(%EE z1eK&|M^Z>mY7ubhkanDCjmK{z0o8sdAV1RYRn&S=l#0j5dB~{xYF`wPAG!d^t6KLe z#4Si*$&;+F_D=!%u}J_E{y;H98Y9APoAG!d;Nm>$VnBXiWb#9`pRWJ?D5d(ff-JeO zjQwSPsQ2tCOS`S<^*;j~*@W!N54G+kr^2E3t3+=2J=YEtnCmBGeL#Nn`&CT=^`Tkz zIpodt)$;~Gew3xrE5B3dFCannmHpJdHy}TpX%&?IqEx&vX0EUH#{v1F?#mQ?8awuN z6qxI)eRM#649fefZ1ta(^%a@gZ`VH%HPrpCs-G@D-Ir4Ps=nHnuNq_hze8Q>dsScU z-+N^JK4OkT`G;y>$#o26=Ju2O{BlQI`7dWe7s*fYp}$+9v}zwc$yry)`n#!)=}`3) zd=X{l_SOEuZrPBMQ?XF>RQ_L(Ae?Gn-G}zb`VERu!u0wlfv5J<^;GpIr`4D0OYV%l zBI~D-v0h1`s|u1JU7xdA>Yw0mXwmD@Lpi6hV}n`hpLGh#XVt)xY|`uJ0+Eg*(#Hz~ zwpAH6OMQBqohZ}oS2$7Br+p{$A+V`7ub1`BG?ZRARZy-_6(m7gmX&0wpP&tT90`6+ zUDEAORB0v>#M4CmzCw|m1wc=(mH(*ui~c?-%|yIH-;JXFaW(KbHl?@BVh<*B{oSRa NKD~-;KGL%6zX99T4r~Ab diff --git a/CodeExamples/Array-Mult-Specialization.power.c b/CodeExamples/Array-Mult-Specialization.power.c deleted file mode 100644 index 10fa011..0000000 --- a/CodeExamples/Array-Mult-Specialization.power.c +++ /dev/null @@ -1,1052 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genBGE_1(h2_sValue_t P0); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BGE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include -#include - -typedef int (*pifi)(int *); -pifi genMulArray(pifi ptr, int b, int len) -{ - /* Code Generation of 12 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t l = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF80F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - l = power_genMV_2(l, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((len))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, l); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0002 = power_genMUL_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0003 = power_genADD_3(tmp0003, a, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = power_genMUL_3(tmp0004, i, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0005 = power_genADD_3(tmp0005, a, tmp0004); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = power_genR_3(tmp0006, tmp0005, immValueZero); - tmp0007 = power_genMUL_3(tmp0007, tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); - power_genW_3(tmp0003, tmp0007, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -void printArray(int * array, int len) -{ - printf ("Array values (%d) : ", len); - for (int i = 0; i < len; i++) - printf ("%d ", array[i]); - printf ("\n"); -} - -void mulArray(int * array, int len, int value) -{ - for (int i = 0; i < len; i++) - array[i] = array[i] * value; -} - -int main(int argc, char * argv[]) -{ - int arrayLen, mulValue, i, resultOK; - pifi fPtr; - int *array1, *array2; - clock_t startC, stopC, startHg, stopHg; - - if (argc < 3) - { - printf("Give 2 values (array len & mult. coefficient )\n"); - exit(-1); - } - arrayLen = atoi (argv[1]); // Get the - mulValue = atoi (argv[2]); - array1 = calloc (arrayLen, sizeof (int)); - array2 = calloc (arrayLen, sizeof (int)); - for (i = 0; i < arrayLen; i++) - { - array1[i] = random () % 100; - array2[i] = array1[i]; - } - printArray (array1, arrayLen); - printf("// Multiply an array with a constant value\n"); - printf("// Array len = %d constant value %d\n", arrayLen, mulValue); - // Allocate memory for 1024 instructions, generate kernel - fPtr = genMulArray ((pifi) h2_malloc (1024), mulValue, arrayLen); - startHg = clock(); - fPtr(array1); // Call generated code - stopHg = clock(); - printArray (array1, arrayLen); - resultOK = 0; - startC = clock(); - mulArray (array2, arrayLen, mulValue); - stopC = clock(); - printf ("C version %ld Hg version %ld\n\n", stopC - startC, stopHg - startHg); - for (int i = 0; i < arrayLen; i++) - { - if (array2[i] != array1[i]) - { - printf("Erreur multiplication!\n"); - resultOK = -1; - break; - } - } - return resultOK; -} diff --git a/CodeExamples/Array-Mult-Specialization.riscv b/CodeExamples/Array-Mult-Specialization.riscv deleted file mode 100755 index 4aa1d4f2ecd1180a921acc40650398f5b9311358..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37596 zcmeHw3tUuX-v607hl@anqG`8vWZ*dQ;&`hzZBxWSWY^SHt8L%icOn>(ceyz;UbhsT z;i8$EnvzRKgh*s+YU;XXXp^X!k(rrmikH;P1nnqdT>jtRbIutCM4+P2=ly*Cd-R#- z`90_NdoJJS`&`d3XHN9!ks6JLQ!g#|14ok1Tf;pBKj9^g^Md~nr{nxM1E=RgIBzCX z9O-DdNEnb45KoSWvqQEcU2-9i$=?Ey-1jSeHla72*2=0I3!BIK5AUO>o z4e8C%FgF=0>)@zdbYDvz?g!yMxhlxy=)PLUTW*h(=%8Sw>{g^RN;#00a#nVL?(|tcUAGpqNbln9<&vVMDg+ z6@Y**Tp%39lOEYqnw$_dASyEFdWJ9V=mH$-JxVv|?|IMf{U)c+0}sDw+j(Wlf$jhG zx9;O|AL~4H_KN3!_s-zEdd~LCZn*61X8qmr=Z#|?zj5vE^Vh|+b3HdNdF*pa+Vi3^ z=X+7=9M=_YGF*j+On0h0I&hU^$$V)urdmwN0kO|*X5BW97T#lT75O=kK z$`Azp(?#J3xJVEEMkF(m%DRD`uTuQn%&2EXe zbJn=jgtQbcURF%ECZ*aZL7#EUJSlmqZL&EjJ}!Q;g`*^hWRGw$qhq5+m>mdrW&d+g=QkaO0>vt5En~960Fe5F;nJ7%8#x;t< zL~dN8DNG#z*Ek9*9bqDcl@9bL3R9<2u9Xgs8^nJ&oL~RphG2d~-LiS`C+ImxK@^vW zUejX{YHA#_K9LXPf?*@ei{5D}A6nN`4s0fmdAsTTMI}w;LvJ;e1DnZXikseFw6>{y zsHmwN*i0U?rs@4fg{nN*P?Ful!g0Y~-@G_4dK?!#Mbj{Mq$b8M=Yij9m#m!2am(iR zzJFc@{OsLxgW=+RtGQ)piMeILnY-uC%bu4(ca|ai+Dps642!IryX%$A%vV2Zsx!Px zh|5u?$@bnm|H5B~Wya`pu4ZkD3^5JY%*)ulZRV7aqg+qDv9MMz3iSi>9erH&nLc_^ zsz<0UGh1(zYAN(hHQgDSIdEch+`J4;7w(=ILP+m-*t{vSmIM+I#Ys`8+G^%KR!ZI5XQn^I;8lE%G^&7t)(K#rtT;5v3dv zTWa;;uG+d7eF&ApRHxTT^}Oh+bA&nT$hOSC`@@K@r&2yp%p-@lVm2pMYv)!f;h1Wz zoJ(22_m4f8Pc}Yxee@WWrLKokxB9b3d}<$zP8q~f3YF@;@_Ce7PD!<%3LC169``A9 z_7vH?_Lw8gRL_SA_1`@HVDy?n8gA3L5Qd8fno2G7h9kAhvghWYWOcb8${}anF(qWG z%Po`Rgt}v88cs$REw-2QMSONJECWW28__N1PcaKWEdOwM8Pj5Ir?vs<<&B_P=|hG3 zhl{C}nJ;FZrTE+tRO-x;n^)f8{<@gOd`K~m%k7*kV*w2xsv%ExjX7I&p_UMfxvOTd zK1-8T_w>-r#&%NKg0yldbywZyr>i3~UsO?jwNlL&>|yyXE30mJLCIUKp^TGFAGGfW zLr|&B5VTJ(CZPP?8uTGTgTnxH4X*mLOMDy1kII}Iy{v~9r-^ZdIqQvCb4PBrlyQ0> z{KaD8C(2z%B^i>rOW|j8KB*d;eX1jazwE>5*PYIpJ6JCk63goc`BZ_kuDY7V3JNSW z(tTj$u1p?zb{|}l{c0KGQRlG1FFg6#P|~MVH6wRq4$b^xsH1Fm*0Qo5+_LKG&a!4q z(BJ_nPo_N5$PTr|C|^FzRX=lRNp>T)f1Q%Gx4>1j=RoP0lNr9~k+;@6H_d-!eqQ9< z?{Y`gJssb@nj7$NNp{{o$J$QZ%ir;9J82MmcQyC*VOr&B0u_$EI+xx_vyqTu1mF_qfe~n-R$6%)fx)DlD%xjO3gMO zZua%Xe_ae+&9W6SkgGH#=Z#vnqMF;5-I*ill|*R3CKEQTt7OB1&%K^aXF@grX{0}jLIFY&+nnp7x-v$ z$_|z-`S{4kxu1ShOn7H^edBk;LdMAM?>>|lIsXE}S=l{%Q@_qC>*+wPcV!+k<(ZC* zdL(Ck*4*f4EWuu0_h=rX+TN}m3vGVwe$KIWKIbTk)sRi5Vsmw%1K8YV6T@u!z@`su zMA>G(ViPxnYNXHi;ZT0m60QiY7_J0voe!*BKYGQ;H4jGn=;vKfFk0#u3%&4k z?#E!pk6R-}(+ZP!?6qg&FgmuxjDhpFHetpm;1ZaD(t{a&RAyX7tlr?kj0dWH6=v+a z;LDiNt=cy)a{pPfe6JFmB4*rMjaG}*1h14^{{^%(aiOvGGtv6Qhv{<5-@Lww+?+}lFdg=I|Te?mKjEVPFR#nzEaeCw@{NJbIN5_*{Ee9S50&=rRqdS@ ziIxUh@6aemjO^aX$mU#ZfrseZKX1(GROsg6JyfdQG4UTMrRqW~e2odYrQ&X?z8%)XUXi!Z1=fAu?F9(#LGeCPAcnEsn;Z)Nn|f5DrL zzTh=j#YW$M61Om_$)oHG?Hylh+cTHWFLCo4y-O*>0i_IgQyJbri;`1M>s2k#yiQ~P zt1a`SrBS|JrI2~zqr>=A?8%eGYkvw)HWd6Eo{W7RJgIGCmabK1=~|Cjn&N0~Mw~KB z*DAAg?X_{wO*}j?>Y3iH&e5JssdTl>l(Y|Knc zL#H@D>@FnZ{7v(>I&&k@=dlJ<=2?smd|9l#i@1lv%8nu!Gu=nA9A89h=KUOx)!~Uz zgM6yBDF5{~dewEW=p0)0U)RsuM(f_|OQ=6xKf*rio?1@l2G@^$ocWeJw|lDtSh?=5 z4mdHY<}CKLH*q>~Q*VF^hl_wS!s&!tIL`=`Zqlwt?=9VgWFU#t>cgd*bx-Rfq?-pE}f#PMOVoFi;L$BS6Ui=8w)MmenKHAwXbeR$zD>?g13jjn5Y-4RJ2a!x|J5^r$c z#CrUuBTT5_MN^GKbk^{FTs4k9!Y$Zcg&jn|;YXfa0-YK&IHuBY`HV`sK6a-pf*w0zXDQF)_L%SzPp3Tk-;wY-8_R-u+v zsAbhMZ=n)3{Q)(-D%TV}?>$T78tOOIeypzdR{Np-ZXm52Xulh1zZ+=38)(0q*zezT zfMt4L=|-Ljt#;#t39WVmNL<61Xq0a72Gr9DmFsKz}O_T5@_*WI|&f(3S7&GuO>jgZ$J z#BoC`cs?II-w&R5($HQNxod9UT`PNt*M?aGQ?MQxAE?mbP#us3O(XmhNQ_u1DyX7KCE430Qu2EVS%;MX0x-9bFYMn~xI zApSv3Q2jH1#9aQ&l&qr#M~V&~C_i*4gU&{8(wcAUe6%^WBaN28h^>{pd9}^iXz6Z$ zZ$~s*LPSeov|%F+`rgo$s6kB|HKN4I3?Ml+m*0*vEs5+~ahQYC$Pk zSFGKT&nuM}2LozotgZQJtgx(e*N0M-Ye}hMtYoP!R8pnUr5H8D=;By|8e(*zvlO02 zm)lNqUMg&|Uaok3ON*z z4&PzB!}r)J+xyhZTREd>VO7>ruWnb#=tISTbRje*(~NQ-NGzpkZxfX3zu$HR-DQNrz50WSV`PMp0^xf!jD)< z{D_srk35}(_7Q3^i&bNe#k{x$^P&s$;t|Y?=Wf!xIO3;;{djq;RpnC(e z*mcas)#@y^csaFb(^>4(TDgxk?U89eQjc`kIH=l>oyZ(i*zKOV@*+PwtBf_+%d)Ws zr^hQb#OB76V&vN7w2<^}o5Qr8?V_9uw~Or$G_EhYQaN!(b4V#CPDZH4pIyj{+Hj+=_hyBf^tYvdRiRD*Eui?lGq_I-#H6@Yn$byLUj~wR>jm z>9GUq+R_f_fyF3wbsIB!wKAhuD>HgEo6)P;j9#tG=+(zQwiL3pa!_@EyC2Hy<`(xo zSU2BdBaW|hldYR?vUT&#%8CuU(8G-wISelBU4$B}o3VFsV(;R@-UU{DOtg2o<0#U? zh;zsN5k?$Z{a;r`oQgT0+&cGBY(lVx%#KAkmR|xtZ!xc zFwbWJZVXdjae;-A|6(eWV=wf1vUc*Ujaxw_{#+&$Z>aw zwZ~jrt<1HEQ|8)gWv;E>6=^iBHU-AsdL{`ytIZSAinLc+Uh!2fleyt${N3(Ra<}s2 z5+`Apb-v?)E>_%k(+D4{`ON*ylAb?4jc1e z_N3q^oMmSBuPp!I-yUOS`KjY=k9r>M|3&**;~p!^Uq6f%{T0tL2Tbuk74mh4CRn4H zTQ_}okAju@qP4S?P~kQ;R8Te>YoJ=Jfoib^s>K?p9-|Wb76N^jgm%LE0I3#x5j>-( z)iQmL<1O~B4t8o&@40${Wi8Hm=vyeX9)dos10_1&(J9s;QZ1}QS&E`Wd9o8A8VO<9 zWL?IrIc6Oq-C}u%O1EB#!M7ABMXb+IT6XpT%iGSDn6;LjCb6?6lw6ccYy&nDY$ViB0(Mx%!5QIn0yNnfmc+^@F}rX{ zVrN)na}74vV1siiI3t`6b|C^ZVdpDdV>{LVuro?zQw1BGQNbDEbg&D73l*RV zJ3pxkb`dzsq4qIKRj|{+E?mHg51bKB2fGlsP&iS5ChP*FE3h+4SD2lS*@Z}y&t=$L zhRqe&T!GCM*jzz5pb5J`=`!qeid~3w1^I=Xf`mEDgmF1_t2+v-htYoa5kb@pK};|aGn#x`NoWn3HrmtKlB`no%P@G9fQB?3)jxl7j2uRFD{#< zFZptoe%*yxZCcKR{NwyN6MPmo84erIs<|%5GbHM5x zusRQ{&I7CS!0J3&Lq;l4ItQe53Q{4``Tf*(gzp*HoP*6d*qnpSIoO;7{-ke|&L|uq zDMUJ_aO5202&7Ui+Weea(stq8CR)yKc!TR3tgp^veRZA}o#!2*>pa$17g}p26>Ha7 z9_8o5Oy?Y7&U3uzI_D6DZ}>i@Z(#ibuzmqpKM$;*2iDI6>*s;>^D0x^SOZ@-*1+A3 zbyek3;B^LgodI5FfY%w|bq08yK^w?uX{9qjE0nNfJ>$$LG`^8d1#Bu{QvsU_*i^u# z0&P&i(5+xt3ld491PRs#sRCGsla!&wXj0L!SPN%(gXs((<~-vFbDiNu;jBY6;d!O= zYr>$MDPDA*a)_=|;B`fNuy&o`4Z_#p_1EC_*SzTZ+5ud^>ysUW z^_*{j*Ky!=9C#fEUdMsg3E*`CZ6KrNCmjb`5z=vnmQgzX1&t_#@iEvOgUvD69EZ(u z*c?Y2kbbyyOc|?>K{ApAtaZ|HHdf1Ng+ihc4x?Sij3L6md4uWS;Pt=3>woiLgF`f( z0IyH92W!(;yutYuc>NW4eVi9f#~q^cICy=$W3c|<5b!z*yp95|W5DYe@Hz&(j-d@? zv;w80Kuf2f6(Sw`ibfQ|_y}x{!saM!j>6_BY>uK0NZ%+OQO0YMLZqV%>rm+^8?TRE zrJi!MW07`#$s1f>g4M^s>SMgPJhuJ zq)msx>BHdkVQ~6$UNn8~5S^cc)1P+?(sSMbTIE2i9B7pTt#Y7M4z$YA0y0+KQaP|P zNaYNxaH*W3L^g+Da|kxnFAl-x5NyiP0;DfWhm^7U5TtODfOLd(h>g{UFy8B=@{UE? zSq@H@gVUdZ)1UF8^D~F&`V5>t+#aM|hj@eVDLDNpIQ=Ovx;}LP6>z$|V~{?z0B9Wq zS_gsFL7;UIXdMDthtL8tR({e!U=<-9WLO!cgWnKJgzy2_9DvOM*c^n-LD(Eb3y^-e zbU+!Y4?r@K#763aY@|N8n|jH?jzwDdgg2Nz0jEC!r$6Dr1czuk1Wq4n57MTOd4rR_ z)%!6xeUKMT2OXmGAUJ)nW03AgyU2Y&Yah@$0JIJOtph;o09ruCDp1-7taJ)iA<}_w z2_-^!FKqU~W*=CHp!SY3F|4;MxyP z9{{Hh@S^j8Lv$Sgr$25F(ylUadLKBw51ih|i>`eRQP>Yo@9!9-7k>@3_5!WFKx;41 z+6%Py0-~5^`*u-upeFL^dwixM1UgjSDs|*tpOFE{3g38K+4SB}i;Ak!tlsQCG88}_m9;8h!aM}ec+vEcLv(%w zPJh%fNLLcVdw|v+ptT2R?EzYQfYu(g0AUm=?O}*{OM4(0NCINv(jH}pwKirp_`4^V z7jCM1E&(UvCY*>n@ogTQjEe$J#7#I6cjAeBYx`T;S2+yMJz(Y@F!Mt&^Fv;Aeh6lM z2xhuq-O6sU*^U@%NB1tReDU$h(mA{71QIp4SXuf(DQaAb8keHRrKoW!YFvsM?*V_P zo}yIBYV9kPLJB7dwT_TVgLzktT2EIEZxHaT(S&D>c;+a&ZaG8&&l*km8-=#(=_-Zw zZdmVz^=?@2hV>p;@A>)l?0m4Yv|$sgXE@b!*e29*7wWhRb=-wI?m`_)QO8oWI@Qb| z?PB%xlXgLhAPMy}O1sb>bW$nW3{RcsE}*~A!MIfF*)!UOLM!bhw|1*sx#Jm(nz!%) znDzmf_5qmo0hm?_rctR&f#EOT-Iu=pzMK@$sD6En@RCVLuRR5r~~T?cHt?^X4wAU)2zZ2;1gx*e|zYFN^0{XkaK*Bs+ z+R0iVK-vk(ND^8=C+&Kf`X0604p{DhoYTUA$=8 zsosdGu5Hab*MA`no_`DRhsHi z=X%t+9@cFl)@p0Df*3}@=Jiz12%C(EuNOOFoY&O9qkEaYA^HQp6~+W{UE$Bfc;#yE~KE`<08zJ^LWz*mDrJlzh+t{t4dv6V`2xNb#a{|MyT}UtEr0d z^%JmdE7-ObY}*R9Z3Wx5f^A#Dp* zXbUjf0*tl*qbyyI$!73mGkCHYJlPDM zYynTUz`7&*cWJ{djMCqEvfg!>SU+|(+F&EvU?bXKBidji+F%pfU=v!IkT*yhSv&Yi z8zDuIgmy4W8_^Crw1&s&s=GZ}o9)^}wAI#ZrT;4<=DXm+yWqmR;KIA$!X|KG6S%Oc zJ&3wz^*cSKDPMfEvNUZj@LCVN)&sBgz-uG$+6cThg42XjxU`;O79g#MWF!fg=@^2c zK&}PMe&Hk?xE5;XqP~{1llFgE`fFl zv`f&2CD7DKCCpAMkrYZ2>_n-AttCp(9~<{B;SyP`Lm4R5^+unxoMW0`XKEI9^UF#g8@DB2L2WYqQ%vRxd3HV(CewTpXCA=uS z?GR0GgWqq%x|P1w+MagK2bCL#9bpJZ5W;glN3Duct76ou7_}+}R>i1wF=}1RkP@U~ zASFtWfRsTh##7&LiEN5sQv{nL*c8F02sTAPiu6OJB4+I^6+tqP1nY3A2slTOR7xWY z*n-k3Pi$1wOvSvxSqzRAgQIWpqUkM%=zI$teXF&4xA}y<&A#C*;tj4MK1^7P@qH~X zI@dZx*IJD4#U0W&N-GJkLf};hyb6I=A@C{$UPWjF87*I_5NL%*A7~k+e1?`zD!@~K5Q#8e4V%@l$%jooZ1Q1~k2WCv2x&FLI#5~-NvBwc zNcq4zl%z-+P4Zj9+Vlo*aJ~UvzX4ts@S>@}Avz1d>w;ewYv=2{!Syo+y2}2fL9*yS`EBb1FzM2@Om|Py_y$Ys~w{7 zI(Ys1uZy*i2VUoa*LmP|9xn>7IYiTI;Pq=AgY^gW4Ukp9YZdTX1-$5_Xch2Ug*I5l z&=RCoKueS$0WE{H3Qv8*C9=tdO)hM5VUr7+T-fBI4M;y!%4OExQZ6I|Nw5x=a@lyD zdzE@hZc9j;R)N*4!0J_C^*?yg^bd#V{0CV5k6#yQXD(Qs3s%1hR=>)N&Q~3x>s7FN zRmULRi=Jq$09q@6)(W7t0%)xOTDfQe87p6D1+WU2Rxqq0q!oDTYm~@lIc%20W;tw@ z!)66+R-gq)-ykh#Nc&04Aw`e`q>a*YHd?R1^UM%wMN3G#R`3R4B{;njoLmn_@!W&GlfYYyl)35MA#etu{0jF1V4AOJn16oUg)>5EF-;7!gw3Y*{DlK5v-qHd{29jVME-hf=^n!P(mn>)r zY12Y*dLcNy5S)IA7fmlYMCVK3^h>`k(#{3o^a61DMR58>UUa_b5M3{V(+fKW>BU!p zRu0h00a`ggD+g%h0IdaR0U0Y_DF;}EOF0ay2q_0oeT@>?WWgp2Hd(OAf(^A=4qAZp z4N?|E+E2=Y6hRV@HcI%#J&Ywec<+OyfD~C4-^TFx);PiZ6bj^35J;CV(zb?{3 zHg7OxgVWjIbT$uE9HI%oZ0OAC7^EwY11%@easn+U(8>Z@SwJfbEkGEBOHPJZfaHW^ zBngP=7-As|KOX$e^2DsoUE3Y^xoujux!*HoqDN$+M`WT$WT8i7IYeg`dPG)-;8nWe z6}6@XE9v~Lvb-{X&Iz8LCl{S2K76akx7mT`Jm5JGcshZn6L>m-rxWZX6eFa04AVeq z9weQDX^7-xbC?sY+jw3fBDSS5wzU(ZJL0SE#(&wfR;PnExE$#HPV{~!FFKtL(S=eA znH_?0{;Bi7?7RuBEw_SB$N>5oKtBWMX8`>Suss8iX{DqE>V&N5|FS(%njZQHA&Ba1h!kzVUn4acj z!YY{Z%D=!Y)wma)))!pJAokEH&I6079CVhMnYeYOzVJc@xRe1d%|mVGp*HhSn|Y|s zJk&;J633VnLcHQ=hMyN4=u-ZU$bnj849UP4l7TTKgBOLl4$(9hESrn=YW2iQegY+* zT*b`c4cT+}u(COslXk3dtntnupD!B8d`D4MhFAQ(EAjUn8A!Di2Hxo;%ZlD~YAL^V z_X6rcmHETo3(s1g#jnvUaI6`=V31Ey}k9uo1XK#(%oaHlotNX7+sQ1Y&wd0sS4tgW^6%Tm464i@D*@N~2l5?wGP}SB zEUMeFGH-A-cL&!>PaGD*rBJhA;k>7Jmu9Sd>H*bXcm!nBz@mc&;U`|IXIAi>2X%-N0I+Yp8eXeP){*sLy+IUgT1)O%KTo1B{c8VJMjFRM%>q5(i;kE zasRj;zYK@+;>o(RZr)0?&sX|T#3*Us^Ei4+J@EKaA5vJWrp||%>N0`SVtm6IvG^qb zM;}w|X7B1qlpkSNEq%jfXx3Kti^(yM!~QUOUH#)|JriSv33aDm;U&o-I#JKO5%K=j z4F8y6(Ep5$;`P0m1=xaLROX?LlGdLcgSz)|;y0b?*GB1gM(H=|wOrVMcrL8}zy#e8 z-FQo)F3g7C><&xdI30)I-?t3C$S$xAEI;rays-4 za^!=$kxWS!pO#?JC0bG~R%Xk74gBdiYid$zVuUU#CR&%2YO`CX#4HCN;(7v$+WdwF!i4j|`$XW;`yjf$(a>-&#o?m3NVuMe z3x!XY4sIfx0de=k=b{3GqH?q&=W0gpj@lQ+-bg@pGvIX4LDku%!{*6ZJ>w}a_X zf;zfKZ3exOik_0E_IFCAq(eOLLpzJI4(h|o^%tlFspT34odD?AWgU-lO>&ou(jx8< zr$)(oY8|yhJ@Q))9pc-w&2*kpbf|vYp|c%2D-@l^`sKLmM|u^|6TwN=j!}V)F2dn0r%L+7HL_C`(f#1F}dZ`3rV zPIjc9x1*uq&$3w&p4v~xD}93U zJqR7Y>+Z6SYs_|!T+VSaZz+lYT>nAfKM4E>f&ZTo7>aju6~g7fVVS_*Wu=2p@0aUM zJ{-M6%op-~icD+20LZkqqxl@Mnw0MUUWIM0nyvc`53-b+d?A>YbyTj2% z)6o4Hw4>#?Vz_Q_^ct%kaCSk%!sPoxru+0>H+n@@eM3W<3Gof^smxXILm~g1D+xwq zse_|(s29?1ps)@v+4?z--n~Z`eUghAF=B|$fVbH_s2ecIIMCRi8$KS<>?LKKW)y-# zke3zj!b=*MKERwZFulJyjzW_LrVlhH&__JQ%}R>5S>?baOKQ9Y+K5cS_G&;nP1Wq8 zc9H8sErU9sZ4E3We-O@EPJPo};|)2U-Zm!NsdxG!fOq?_NLDLKkS)-O8B}&nhIS&n zesm+8=gOf<29#;wZkRkkN_5d{&;*U|X2c0vpC3?4LGUq=B=`&?PviX_Jg>jvLnHQ} z6|122+62#QEj~1c`@<;w5~!njuv;?1odqwvtBv!TN4LZ8ru~WF>lHz1`T7hYPw*N5 zFGxVXI}z|&3}fxR!Oud|%Zv!VXYg$(QT;Hi=gR{wrv9qQ&}uApt)sDUU)5 z`H+Ml;UDmVAA@SA-vlkkJ7+k{-;+A!kqVa$l7~{ zAMs7g@e|;&JQgFs^0@~IA|GJJ{B_~7S15zl!$al_|U=l9`hy6_`$fTp%3jcQlm!YU!yqs(5|JpofP*j#nFfMUlccq z;;3OY^r8Kf;&dn}{}sj2hxRPR{e$$rr#Sl1R#V(`RF&7@Lqi{0e+p64X}eQsHHCUn zXcL7Vq|jap4WiI-3O!CCf>j$sA%a8uM+y~C=)Wnnl|mK@9iUJeg-%jvCWWq1$Uz}$ zOD**nub%ku`3+;T|03if`1GO%@;(GzpWdBUA`C6^d|v4K9>U#&d`@{ukOPk3qOm$A{psAbDhYZ?l9Sh>$Dp(HIG7k|1-!m$meU~f%jG1 z^EuaPKawN<<714f>BHT<2hlzP^%uW;yluE~R}Jaim5739?iz=?S_~Z8t_bwd`9=l4 zO-Y`ChOa4*`YPwW0-wIozW2ck@D9Lj-;w?s;RSL0EO?#hEtsVUC}rz;3Q76K@RX3? z#nXFIxxrAOF)amQ)+rvK!G*3a@U>l_s_EhXTgYDgmS;5_FON$C8CE}}7Gm)-MeT1n@_3PXLMZ3&Khz)ZS>(L# zhTRbV$NUHTlY;kM9^#{zVSR!T@jDF6zRDdhQlvYbG@9684Q%{+Bhh|{@ekJUf&Tt1 zwcfsTD}WjG_ED3+%YfAGhiYIK4a)7$_qwlF5a#F3N`ZWVA<7JeF2Nd>60)O&x+=wF zxnp2^$fKCU?$P3Cshc}<#iV-=IR(^=Qn*_{;fDJAqx5ohDYA!>i=xxhGua%CKc&k7 zY|o-RIF7;l?Oul>~xpP(CPe5gMszx0)hPM$Pqp!w-EYXWD(+hOAp60GJV zTbhTE8fQ(%J6xw?JpfHRXG=>E}+#98-skWrVR7(OY6sq%xnd&;= z5vA0RqR_46HX$}<%<$22W+*k8a;b4Cc=;`5mykB~xnv7xi&LtDwA|UTH}4YgBL)mm z7OA?vDRIvwJubhV8A6gRuCFcK694$X{sRUN7&u@MDOlqtKh9RJDRGk$;^ieOKIQeP zu5Y5Q@7RI5zBYTptG)lAUXW;M18S`)De7F#^U%J9iNlAE7}8K}T8A?ww_S6g1`Ph*JAZjuce$XRWcDdu<^`b}J-&HNl*%Iv=T zD1xAa*&dhJSaQ6HS*?;gV2-155Qv;Pb}afY+R;4KhG&rfr|H!ilUiio9q9EF$GYZY zCZ~>>z`AcL-f?Y==b)3GW=opU4-H}?N%e^<9tliMg$_pGX?V{%Ua;;~Lr1gsgCpNl zUmm1W)9uMkM`$^oed6`(^2^%MYx^ao#wSlru*j)%L{Xb@G75|awxdJaQyV23hDk&T zDN>=m613P6NTS=o5TC?47L#O0Z2^EiDZa1Of;WFdZ0WMonhY1u$v#`7F_}%&>^wrg zkEI+gI+vgeJ1*waxr8iZEryHEE9m0csRgZ6RhdpC@Lp}V%%)v-K0)z3JC)$r8G$U* zX$NF13FzXLH__9QP?iIjACRERcQM)5qRLp~;iB^wx_IU7_H_Ot%R$Vi^A}m}!hH3- zfoE@RM^uJ-AFC!@bk0H-&rVr5?pe1ipT;D+<-3_)x?85xn8u6eXo=N$@$7WSQ&yi0 z%5gk9HS)YqrxT4A&pps6AjGpLu#HhX*Nc-&F2@OYM?E1(?X81Pr$=&$8}HNpLB*d= zot}kE=UnpT&rMcBUp56Fly(hD_&abdmlR_=G3L zXmGk!3SVtM4cCREjV+zQ(M9?{z*pOwp1O8bi;j3I??aGtksdLb(u;AwtlorjzcIl(P==V%i<*+bq7 znfOO7t-+h&_d|ZZlZIQNr2jeOu6`PZBbBc?-e2Q>Z4xCy_Hut<0zRnz-{BUW$#I*L;q>W#n?E|^F&H70sd^rv{fM426>~0KAl2%mTw8< z`@x5275zNOIlzNPwl2V<1hQJcF52$gHprzO>CrI(ji1@!Ee?C*zM;bH$f$~Z^nQxNz_XBA8I z8jhZ;lKx*IS9$2$Avd<)-RyZMr}RhS+j87L^FJDnzB@wpuR^{Otl{WcHOXrsUlJSd zzXy2+%B$k_0pt+aCn)tf06EAb{S%PY@xP0<8+Q?M7WDt3=wF4r!=T~lSuN$qc`Q6U zR($q2tKFE!h0ge;$JEJbSmh?BWBzYxwvV^kZT6{?CSl@Fu;ANb?CWf1dx|+8I~a=% zYtV!=b7FGZb8*S$1bdnli}a~8IIP{$lPz{j0#4Rj)G$v%c4qb+BQtiP)|uQSE7tzz zgsCYhGhyN(VM~`}Z=%Y+deoP`tkib`wm;ZNB+X*q95S*c5{f!`AgpYuG4eO(u+l{Y zeU}aq6O*v}f|#6^I8fG0va4Uydm_&EHycG-EjG*Tv2nH(b2>}h7B|geZWLLzPg&wo ze|)WuC6Hu`pC-pVos?jo%uN`_GGpKQqfiR_Mj&cBa{TZoqRr7`OlC8O&FRLswk|JY9$3~4XV|PD@OP^||-KA%g*-V>%d2f%hC8ajrd`NyQV#e1C z@eMk&hd5!hc~Ij`d>s*@*&H=tf>ND$R>#Jakh2xb&`F*#W((W4navYS!zT_mM@7fP zjv*w>O+*GTm0-MQj!!&g9>{@*@qhD7k>xSoGEL45^`C(CtA#3U^Hg&u`Lt(};{jlQ z&N3s(?x_n3V{fUPd;r))iybRsl`4r7EcRG%6opQ(rI{zkr6yogFE?CGk5<@(aYSJoE!_g`zyA{Y|d&8Q8^;j+)#{p^0 zXgBeR5ei%I)J#?*qN!odXq%a0k9!Wj-75Q&)ex&uI%i~?vf)v&eQ76b#JxfMRGwxw?6K70M#%|1RnSoDh8l$DrGFcglXk+e{IAgli(l{(} zM$d5L$i}k9K?OF9a%zcbNZKZcZ9teavJcwnVh}{GG-?>*>~?F?b5rdYU5yEr=cXoN z@QX`DBdH=gKvQo$_nZ}6S0p;ZQNw^q4N^2((~23Ueb;?ZqZyT!GPJj|LkRIOm1kRy z(<6>{WTZ!XfLz?rA*^1Q%Giae49AzU-gfBGcjefVJ^40UJCH6t1-*gi$CMuJ5d#pQ z{eiqIr1hrk=y)D8qg+1d*~tKDddnWuqxpCQ9F_sH9`=-W2pb@)7fjgo2Yk}=Yf6Up zn)GBuhp?J2#gqFJ96j%*FzrE2(Cd$|XTA`*L^vvI6dXM>r!_}0!jxV&IJ!ssreruO z1KI1aM$wUiS||jm4&kLPFv^NX5gWfLOCrn6>_8dXbt5V|Nv9x^Qm%&jzNRO?3)3FAluyUzo zrN_sr9<9;thn`7Qg0GhEu!kP4jh}^{e3Bq5tLf1*X3C%Pr8Q?V^eBDxQp2YZq3Y4z zl=LE1CFLH8=itbuKMA-k4~IN)SH5N=M9(JFOU;)aKd524cMN*tR3-RS zCc5Yeg{PhYgp5)<2kxu)?ro;`ztcFbK)vaqhvlu?hSCq1f$wCrphtUaitbNJxF*a* zA8M8_-5=IW?@!poj-wmOMM2e3-%zh&bcA#aV7(C$4M*)31lI|UaRokIJ+nEkPHj}k UYSMJt -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include -#include - -typedef int (*pifi)(int *); -pifi genMulArray(pifi ptr, int b, int len) -{ - /* Code Generation of 11 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t l = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x77F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - l = riscv_genMV_2(l, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((len))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGE_3(i, l, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0002 = riscv_genMUL_4(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0003 = riscv_genADD_3(tmp0003, a, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = riscv_genMUL_4(tmp0004, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0005 = riscv_genADD_3(tmp0005, a, tmp0004); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = riscv_genR_3(tmp0006, tmp0005, immValueZero); - tmp0007 = riscv_genMUL_4(tmp0007, tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); - if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); - riscv_genW_3(tmp0003, tmp0007, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000001]; - i = riscv_genBGE_3(i, l, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -void printArray(int * array, int len) -{ - printf ("Array values (%d) : ", len); - for (int i = 0; i < len; i++) - printf ("%d ", array[i]); - printf ("\n"); -} - -void mulArray(int * array, int len, int value) -{ - for (int i = 0; i < len; i++) - array[i] = array[i] * value; -} - -int main(int argc, char * argv[]) -{ - int arrayLen, mulValue, i, resultOK; - pifi fPtr; - int *array1, *array2; - clock_t startC, stopC, startHg, stopHg; - - if (argc < 3) - { - printf("Give 2 values (array len & mult. coefficient )\n"); - exit(-1); - } - arrayLen = atoi (argv[1]); // Get the - mulValue = atoi (argv[2]); - array1 = calloc (arrayLen, sizeof (int)); - array2 = calloc (arrayLen, sizeof (int)); - for (i = 0; i < arrayLen; i++) - { - array1[i] = random () % 100; - array2[i] = array1[i]; - } - printArray (array1, arrayLen); - printf("// Multiply an array with a constant value\n"); - printf("// Array len = %d constant value %d\n", arrayLen, mulValue); - // Allocate memory for 1024 instructions, generate kernel - fPtr = genMulArray ((pifi) h2_malloc (1024), mulValue, arrayLen); - startHg = clock(); - fPtr(array1); // Call generated code - stopHg = clock(); - printArray (array1, arrayLen); - resultOK = 0; - startC = clock(); - mulArray (array2, arrayLen, mulValue); - stopC = clock(); - printf ("C version %ld Hg version %ld\n\n", stopC - startC, stopHg - startHg); - for (int i = 0; i < arrayLen; i++) - { - if (array2[i] != array1[i]) - { - printf("Erreur multiplication!\n"); - resultOK = -1; - break; - } - } - return resultOK; -} diff --git a/CodeExamples/Array-St-flt.aarch64 b/CodeExamples/Array-St-flt.aarch64 deleted file mode 100755 index d2163ddebe7e345e7e3693996edcc83b6672f8a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48112 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_F_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_F_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STUR_RRI_F_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_F_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STUR_RRI_F_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_F_128_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1e4 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_F_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_F_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_F_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STUR_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STUR_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 128) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_F_128_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef float (*pifii)(float *, int, float); -typedef double (*pifsi)(double *, int, double); - -/* C compilette prototype */ -h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t value = {H2REGISTER, 'f', 1, (wordSize), 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0103, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - aarch64_genW_3(tmp0001, value, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ - for (int i = 0; i < LIMIT; i++) \ - { \ - if (INDICE == i) \ - { \ - if (ARRAY[INDICE] != VALUE) \ - { \ - RESULT ++; \ - } \ - } \ - else \ - { \ - if (ARRAY[i] != (float) i) \ - { \ - RESULT ++; \ - } \ - } \ - } - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%2.2f ", ARRAY[i]); \ - } \ - printf ("\n"); - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resultOK, loopLimit; - float in132, res32; - double in164, res64; - pifii fPtr32; - pifsi fPtr64; - - float f32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - double f64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - - in0 = atoi (argv[1]); // Get index value - in164 = in132 = atof (argv[2]); // fp number to store - resultOK = 0; - loopLimit = sizeof(f32) / sizeof (float); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) gen_Array_St(ptr, 32); // Generate instructions - res32 = fPtr32(f32, in0, in132); // Call generated code - printf("%2.2f, %2.2f\n", f32[in0], in132); - CHECK (f32, in0, resultOK, loopLimit, in132); - PRINTARRAY("32 bits : ", f32, loopLimit); - printf ("ResultOK %d\n", resultOK); - - loopLimit = sizeof(f64) / sizeof (double); - fPtr64 = (pifii) gen_Array_St(ptr, 64); // Generate instructions - res64 = fPtr64(f64, in0, in164); // Call generated code - printf("%2.2f, %2.2f\n", f64[in0], in164); - CHECK (f64, in0, resultOK, loopLimit, in164); - PRINTARRAY("64 bits : ", f64, loopLimit); - printf ("ResultOK %d\n", resultOK); - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-St-flt.power b/CodeExamples/Array-St-flt.power deleted file mode 100755 index 652c5e42a177b7c559ea7c32694a4c39e52b9183..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78544 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%0DA1zcgQJXY3`J zKS>Ptr$SO!8Kgk6J*U#-@8fSQ(d)t^H7BWKLuvA#qK#M_PpW~%V~OUIG4uE^o@7~iyPJ5)_~lL$l7-6g@!Z2@DLu3=tin=+lclo+cXd)?Qj`^fk<23n z@k<0Z&b19+lJTckU*DC#p&6D!Xtv0oET3E!#gicBYFsjZd9Khp4}_istNy3_KmFb( j31XhXGf$MXQVm?r9c?SEFH+_I907yl#-s`-McMxaKA8Jw diff --git a/CodeExamples/Array-St-flt.power.c b/CodeExamples/Array-St-flt.power.c deleted file mode 100644 index 2b64842..0000000 --- a/CodeExamples/Array-St-flt.power.c +++ /dev/null @@ -1,909 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_STFS_RRI_F_32_1(r1,r0,i0) do /* w */ { power_G32(((0x34 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STFD_RRI_F_64_1(r1,r0,i0) do /* w */ { power_G32(((0x36 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STFS_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STFD_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef float (*pifii)(float *, int, float); -typedef double (*pifsi)(double *, int, double); - -/* C compilette prototype */ -h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t value = {H2REGISTER, 'f', 1, (wordSize), 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x381F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = power_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - power_genW_3(tmp0001, value, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ - for (int i = 0; i < LIMIT; i++) \ - { \ - if (INDICE == i) \ - { \ - if (ARRAY[INDICE] != VALUE) \ - { \ - RESULT ++; \ - } \ - } \ - else \ - { \ - if (ARRAY[i] != (float) i) \ - { \ - RESULT ++; \ - } \ - } \ - } - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%2.2f ", ARRAY[i]); \ - } \ - printf ("\n"); - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resultOK, loopLimit; - float in132, res32; - double in164, res64; - pifii fPtr32; - pifsi fPtr64; - - float f32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - double f64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - - in0 = atoi (argv[1]); // Get index value - in164 = in132 = atof (argv[2]); // fp number to store - resultOK = 0; - loopLimit = sizeof(f32) / sizeof (float); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) gen_Array_St(ptr, 32); // Generate instructions - res32 = fPtr32(f32, in0, in132); // Call generated code - printf("%2.2f, %2.2f\n", f32[in0], in132); - CHECK (f32, in0, resultOK, loopLimit, in132); - PRINTARRAY("32 bits : ", f32, loopLimit); - printf ("ResultOK %d\n", resultOK); - - loopLimit = sizeof(f64) / sizeof (double); - fPtr64 = (pifii) gen_Array_St(ptr, 64); // Generate instructions - res64 = fPtr64(f64, in0, in164); // Call generated code - printf("%2.2f, %2.2f\n", f64[in0], in164); - CHECK (f64, in0, resultOK, loopLimit, in164); - PRINTARRAY("64 bits : ", f64, loopLimit); - printf ("ResultOK %d\n", resultOK); - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-St-flt.riscv b/CodeExamples/Array-St-flt.riscv deleted file mode 100755 index 29fa139cbb89c72cecd6d6422cdbca563d5e9e38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33332 zcmeHw3tUvy+V|eGHw+3PhGuss1~$YCqhfWs8sZ>QCLXmqeedZvA`HlPxXBD-+t_@Aqr# znzf#_o@cG+dG>#;z1G^By{9CO9M1DRryV-(7mlbVKc2e}@!CIgoFC%*I0M&{i{gx2 z80XJu$|D}0i-!OO5&0AZ1UqOu>ZK3{ngW#}o67TF9*=~2j8$W;oOqOjQaooK!?8em za3M+^q6PKk@hqf+Z5aaTMddn*P#%JE3N4^1P`Re#Jn+whZWIj2r=XRM{=uFe^%TcN zJ;k%oh%yRV`R`E<@>d7dkLI~CDEHN`4S5tu9?fzCva==($WD*V&dM#E99xiOOM78( zTx?c${@}QDlP%9QNadxvh(Br6)A&`+1JywX`M4KC4+LuWCImVH5r`)Mp(g?zR0sKv z{1S|y9aM)NAqaue#7DA}#{~@=q>G>V=~Sv{s_4+lsLqi8D*f~3A7)10b^l*&YfsMI zy81u<)OW~V-u&~U%OASw*1z;D_MC9`DR}gaKbuB9b|x2b<=jVhyn{HBpt;FPdm-E@54BnEQ~n>I zLwxApfgb2XOQ09{(8-`HeCS-z)jl+rX|?C4W?F4oFI&0%Lc5L2w-yxS6>!$cS$4`u zo0wX_rP}i{=qHQINzKmAOXDmS;3Lgqv!@o=Ejg)Kxm-?uL7v^32AP7aTzdvM7-%dR z*@d==maMeYw24+O$C{It{}M;C1fmDHq>;%9!z^*8!S{702SYY9J8wd2wk1Cgby*9- zp)`=;`;TXopym-SbX+002#<8EeEm&8PT-~>O?jU%TF1?%LLA}wJm;r^FN)GCXk#c% z0L3wo(yT*c9HF#wTDS)(O@PMnD5V(~IWC^k1YjIyN)upljG#0D7{^FTt0)^yX%+0_ zC`}y&$6Gdz8!T)bDy-O887d5GFPV;btdVmpOyDxnJNo?vmYGI{|*+VZY+-LkH9@I~~f54)DXwzMl<_d!=W_#%2#xmNyA)Y9U9i5wT| zw<&mf;%F{(67QKdoKNaG^RCBrbKjc8aV694F-)I|xOn}vP=vGqH&+6$Ppb(nT0d=i z@${)wQiAk5ua5Y=yfmC}@vC$;AQR)Xbl?*A08<&_meJbDE zzbRysKP53m+tXlIhk>YgW@qZk^IfP1(m-pqjtBI6i=H8&D!T}R8r3N1~p}FpI4*giR}$FJg0aUXKXVUfc)Z6NCpiXJ*-dC zACmsIv3}zlHH?d$JMA10U+FNi$`~$o++R*s7X7v85arJsMp_pQ|KzPR-1Bo-&PK|4 zOgYcRiZ8&SCkq9#HR({x(Khl}(xP*Nj81+=`?EueI?t1a7SuJ9YIn7N@~k_)=&zbr z=QnHZ0zItVk{Y+?6}4^6Ld8!uV@T~UQ6bf~sE}Htln(v-c#L79#}NhZM!7l;%?KLD@SZt@Pw3rFnmk;zPQ~ZNc+xmN(YxbAzlr3G z%f6rK_mEL4Bb0Xx*0%t&uJ&_tR4=gFi1)7H>xu-l*>}*=;`ucUM@u3edgbY_A0U3J zl^?#QXh_l5LmV~JW|Y+Q<4WA_UJ7SY`9p(pp3WN5i4N_IQM*EftK+2ymKJyV_PI$j z_AcDLc<0voy1J>I z??_DM1ZfuMkhX9_WHRqqlFScz3%Z^&F3@wvg$QK`ixJ8ZmLe?Eb5!n^I1|VK-}F_C zo?AoIZuZ;$%p26V&oykjcd@s%er{3K>}Iz}?fjz|V@uFEChdso!3j~&B?7ucKo_Y8 z?~sytA#xUPT+ok)Cj88r?KN|^?cO$T$J5Ka_E4>gl~gM%V72~Dt+gDrmZR21sC5x) zU5r{6qt+#ts`ayFrSa2#nm3~T*|ffHZp%YUi%V-AsQdMw&;pO#TijeBa*a{vIHAU@ z`14kGK!X|Mr!H;d(SUho_#NIZjbGGElFNTmE$$0X!{X4ll6d6vC2zX9RmHuy({rAm zQ#zvL%@?_%%#vdL+0%2rofCTGcQ^~vW|z!Jg73ec9alV$`Poq}!WJ_()4bh0cf{@y z^G5#KFO!yf^}5ZgmrKol#TafN$3oHJD4yyGJ}QbH$8liBDTY z{ro;|Zs|XRy!tDCU>m(Iatn||NKWQSs>mz#<#e+4S5oK&kXiz%C6EFtNNSc>D#gRl zeYIYYq@0~l^eyA`qYTS_N%L4Q2n8w{Sn8E$=WRp(Jy$ha8u#Wn|L4vmTiG=+tWLQi z`g--A%uxM{{_{5S=nJln0(P}~e$tH13tfvhY^@%(e`)}F`gx_N`{MPc`!0poLCEcb z*M5YH_mXZPTH(K6q4mPGptVO?SG2BAO53DjwKrk)Q-;+qv_91D@_nc%^OF7Ox;0z0 z(5u<)-hOnQy3M-5x}9RPlj6$emH~Txds51t?)0R*udk;k^{PXkxNwy#!v)}Jl6BpDzaiJ<+GQVl|Pi}oK6@B9ANi%8|Zd$x?>-td#ruG2R&zNRa&Z=_G zi^s?siYpp=GE#T@T*Ypsv^pB!42*2Tc)yr>G{$?3xs4<4!pP=wUqx%TdOdTi*E2V} zp1Ile%&lI}+zs2TWlWP0caXQu+uc1e6FzHcwA5^y2A< zXRIrdiki9l;dJij|0F0^wSI06`s`Q62^uL;g6jgVcdTSbBTC9~#nWaGq3)hE*0O8f zS4T0&m_=s<*FmavJzZ0{Er&|uzi2KULDxIw+OkT|#Xmm>WnHd)kN|zr)$dZ*7C@(x=J$R3NU!%v$6s9uE_wavyy|@PF4^=esY_lzIV3q5PnB>!*1_DH*)_Bt||jL^;pn zx^>nVslYH#b?f`;5FzQ?MSq#29+zk+-RT&DF+G)z_`c7<$fU z3_W-G8T*>i(c|78*Ymma$xmSn&6#ABdWRUpr-c~9UJo%E?&)23fa{5|RQ8#r(7Ib0 zJ80dFt3-)+-L3X#T6b@{c$P9)@76*8(^r|NoL1*4r`37NX*N$e&E_em)p^S4hHam| z=k1ZVyMx%cev3P(am2Yp7~9WYZoY!`IL2bq*XS>w1r|xHh!l z+R%b)Lo2Qgt2y*l5oqeVp{pHJd&UVz598YJ*7*X!E4&>O6=TIy2GpCW>v$RNy9G) z#T<5yF#;^79oj4G&0a>kORb%+Njr7LTn&6x_>N-DA6SDO>($aQTmGA6c&H%->jCUPinBCNA|Go10RKeQ}vLqdT~q zGyOVnS^v1_I&fKk0DB$(v$zc9`T1CfWMCbV5i0VTnBy+MjB)|ygKd}(wqZWlhWTIz z=7a1GFWskSbNV2;4Rd~ET0Fb zL6r`Z+m_R6fohawYSX*p3CS+IN4SUYZ{(PCn2eoG=X;PlkG3V2hg~FX_Ijzc32R%& zRwHa}g4Kv5pM^BmCTJTg6KIP)Q3MI$qIofs7UeTc%QMXGDESQ5GSM>0$dHjCBg1#t zXGJg}7({TgHINLsC|PE5(X!0eKqS)&nO4YPzZJoRV1Qhh2u{ca$gNDXRwfrCw?fV& zw+fN2_l#xV&-P0)I=`RM+|>N{=;9T{#s%NcHZD9h8&7f!pO#pJyJYTD&Glb)U?iT7 zR$9;sRz(OV1Or+MLkJhCg($2VsJ)(Y3#b^P;2o3Pg7yqDwcd^=B3erV#D9H9_ZM;h zP|wv4`&&|d(i=}UJXxB8`rpBNq!j2WHJV(dSdYAm^~k$8Kkr^v;-8Rs8xn6r;%!Kj zLZTEBr2^J)LWKF0Bf@z~kX)x6@RJZ}Zp9fVf6a&7Jjl(1+&sv=4Y{`=_cm5O^Ra69 zCssc1C@Y`lro6wyZmg3KOb70ALGnphZIVwis||9?7D6-m>I7s?K;|T5 zPD17+WKKc@;*XI}FrNj>CqNlg=`i^ud=^erHR07bML})@4|EM!gCAY zxdqU60X+9Fc z^n@TePdFsk39L+ic0`(gh8|b&oOm3VI}Xep7bMqlha}>@hWRI8?kC7~%X9r-gZ0N? z{V`a74ARG7{V`a73?4nkY!~HYuw9Zt!S*Qm*w-`yk<1au9D&Rc$Q*&p5y%{YM~OdN zKEkB^EgxpK z$H<5GP~Rn)gOE80nS+oy2${o>ISh{yf0TTXd9J5?5L66N@SI6L$VND&t}xVjoxRm{ z7?}G3nEOGHoIf}u*AKwl5nzta-Cl@X`e9 zn_ztttUn0r55oF`@Tg*YklX~@O>z^n-5?+Qmc}{q*nY_DhfEV>njq5znI>pJ{4w%= z=DA>bKPZDL9VR!iajxkUp}6UK{bv3ii2L3V;rd>HmJZ2$P>6IM1mX@}*>BDRLWJu8 z5Z5F~<|c>aYy#q%fVl6w>$j9$u)Pts?}zRCVf%jAz8|&hhd&j|Ic9kn`2m;-m-l~1 zHj}>^A=3z%M#wZmrV%oY@Mk0QR3r17P9`c`1_fzJZe*iepS3WKk&9+ zkevG+l50Qkb^v%gaAm)Vjlf$Y@YX0uu11F>eh0jL2fTgPUBB)461MMy?fYQ+K1lC_ z?fYQ+KKOGVvs{$-!E#9k1)7~K_Z}g*?t1;^+5x=P18?<$?hqrL5DZ#&xi3hjM`_P#=UUqS8)J>Iz$?QKPS z+tA)Nw6_iI;hru0c7+~~wa34(26-pcpRL~J)BQQDTbGvvIAz!%qfQxho<^OgQRivY zc^Y-nD*Xz!o7-Unp51q~!-fvnz@9UQ4INjp{Yt*RtnEyHW%W5Qq+9yQ0Y9Y4;a$6v`1#(*;w-s`P z?Cy-_^`6h0tEZfU)MnVf8TN06{hMKbE$pu~hKpo%l)Rbwpr^bUR18t@fr(LJ%m;Yt zO~jpGGwuXC&kB<3tV0rUC)kWT!A`3E3fK^9AXfvq8pzc^t`>55O4~_i<+8p5PHA^R zJHJgI?QO31(0bSf8(gr#1sgWQhRv{HGtRMML6Gc%1t!_WEHKEM*$xBQy#X>CAmf6J z3o?$H*I){lW4EPzF^xOm?v=6Y8p_@z$ka!Mq7r-vq3063{BJzFCNLZU)vj zU&)@!?o3<(1(YCFRuj^MHHl?<+bcu1S+0-;93=P>wvj+z}z}P62Ejv<}ZP{ zFM+u)Z?xx}Yk|47z}y#tWd6b-Illnrz5wRP_HJRW*IZb?22yKa{Tf)m2G*~E^=si# z#r6Ps4Q!8=*D%{-sQ12)v$gwJgV3pBv-+9lU&7YH^{5m4g+~?C1h4Y zrV27ukg0-96*M6J75$B;fw8|^o-5_qcw-YNyjRq2q#Pk^^ifVWS&>$fR;V0#5@ zuYm0pkgkC36|lVm{;Xh@i*f}lmt;_|JW8%$Hj~T>$gF_O3dpR0%nHb?fIo>pTwcMX z{pA&)qKJZYw7i0iaVyvk!wMB|6~J2s@Kzy6;>Qlj{4wzMG4S^BjrN;!1@N{4c>73@ z%pW-<=SRTXN5C6d-mQM>Sr6NnL24OnUk2Nk!S-daeFglfSRNoRgXPikGG=*+Xukg2f*700@`#)=B2>fQs8arjrN;!3GlWAcqJ zQwEtb__K_8s*L$fCleJegMzdqm$C7!jO{R#sd!riye$Ua77LPdu|sk#2HutcZ%b~p z-^4QDt;`YOEE6PGnL`p60dIJM#JQ-uew$JZ+ZV$2g|K}gq!+^Wg|K}g{J9Vohsg_> z{h~~iL=^0gk{81MXhsRZ)L3K7nQK<7e165n@7=J$cl_Z^Y0_q%I* zug_=|g_Ur1p4?o$W1fJ&{4*~8ezve={cO6k-CX_AqUaebW(bS;*^Wg+XAjmdj(>RO z;0OKrPl~JJKbfH)TIIdpO@9|be=F^Juemw}2zI?UqzF$DX5cBp3_RhGIelv1Ni%jV z{Ay}%qf~}F-YZ-8;2w6(R$&G1W51uoIm(N1Kf8vT`Q-K|=cepVnK!m^tkK{)XADcn zUzGGYhqHsVWEuV@YvoyEj0=C0g}*j29LC>d$>;HRrp3iy!Iodv%m~$Ueh<&6!rx>! zSM)z7M7mmMC8cdW%F$n_)@*97IB?*Vr<*IL;4X!;^>uyeFyi|ccFfDL8{=$!PtBQf zaF>2j*e-X!_{eCvtr+hh*j21gh`bL^Mqm%)142bxs2>;KT;06TXeetd@#A#Bep_?B z(}>N_*U@}{kgHI)m!^OdZs|c z{dIF|PlyRCbyp+%cEH&;Bq3n=Y)b%DVC+TGcKzX;cLtxZpQM!FaL1NTc^ z>RTKl7J#QiX;F_BiQ47X*Aw6CxI3uvQGVxJ0H8zLp^@&h%xg99*EaN$j=ngrX0cd%5ieoJ$OXOrSf_)ioR|LuVP z@Ha^C-!G86pugYQ=D_|D^WS}n|6Wu4w@NPyktoGZTBNTQn!jjG+wqR-FVX9-PHFw` zoNe&K!lLF*Kim(0i5&`$9xV{X{Dm_`yj^`Jl9lv!3UDzipHO_J--`1^>ytJ=>I?0i zZFbRA^B3lTcw2%VxS@T)c2-lO>aUNx_^XmMoquRrQtt)yUWShNTyrd*xy0*G*t=jT zju@22MGTBfH#}?@W6d-~*zmrWh;+Q42W7~}vf)59guEy=ILR^9P zZ)-fB2E;oNw;?`@*r4OM?9V-(5r|hJ&PLp4t;aJL@lwRA5!WJaLOin??cx1Lm53ij zT)NTYu_HdS+2dJ;_~Gpy&tb&>`)iNqPP}_*?k?zqIBGBSKwRD6@l+!&Kj-nBK&-vj zNqBh-$N!n<@3=|F@@|EV)vG)ndhZse$Gg-J#USiO9{GU|%8N&6L|!;zIt&Qo5KbWP zPQ+Y7a7e;T-SBDr$n^=e3GA&*BsUr1FnC}RI}G^!8^TWHJwQ1L!2=U!@(Do!Ty|}c zZXiig8x;s7H(KE_n5XeGb;PAhK>a~F0~m>q&Q}o5O|8N=u#;~M|>|uKS5iB8^UL(L$4<5V1p&o#RB8cPuP;MGhr85t(@z4$W8phFj!kQ@FL z@S)fjKSC2@o(oZ|i)T7AzmblUA@kr4k7wRxeDase_@n}I^U$}uBNv7CjzR7$#)4x8 zQaHFJh$(5NQ(I?XR<#6~p&jw|5it(Q9?u^k1OGMgUT_Jc6puIY3Ib66+wq$Re)GU@ z9{9}zzj@#{5B%nV-#qY}2Y&OwZyxyn!~-38`Ec=E!L??FsDw;&clU(b;RA(Av8 zkRIBBx;>O`LA~7#^xl0s=$As$uwf4yqVOjBdkupIo8n9ZxuNv>cJ>}~j;EavF~qL` z@4?TC%O7OPiOU~oNu^XqTz;G-oqp0N@8zsCTY-|uu;!*&!HvwEoWkru`LqmY=R>i9 z&ItB1aBgWms~zND9jCovU&~eeu48W`SLC#kSS0XHV3x@&q6*pO6d{82=BMh$AsRph z(E?WwRuZ5_gV#gkE@GnN?+79v@Couno&FbSDT;bCQKJ5Fig^D|5&1ojA71K5yEUTD zuM&|TA%~B;GlJ5u0y6x)eX^16CHmnV?wsFrDvrK|_U6O@KiYy61N0A5B>D|P6ar)f ztVP0a4uo~LhmHrQp9LAht)W9H{Q-W2+xn0peoji?-iLN<{r(d_V*i`hBkCO_{wVec zhETvqr29`|@K?y@0yYtKLZQTfWV9gutWW{m%^wnZQWU-gXAjz_`VUmllQb2eq__Z- z7$W`?QRpLJ?QwU=8z|$)`7J?~-<{0lz|$xR@n7{avi#pe+W#}ZB&0e2pU|}bnx0cY z=s004BG$$nBv>0aaXe+}C__I0lEQqXc>2-3Pk9}bx193mN4JXd{3(yl98W*GZIl;A zd3z|2esl-$6Zj+YLiFxv(%~CuqsJ?ukk9!$QJ_EH>kC9W|5uTvztHD>5TgHL@aj84 zhX5nkbomiQJpJefAioc7@!qNT=L23tB47`(2JlLi0Y|C+9=uX#z^g>{DB^rLfA-it6*;PJ!Lk1mi>bn0|{DfKR;`ctZsQuk77 zGo=PoY9FN@qZGMSmqaOYhwk^3T1ct?q*N89td!bHsXR*Ur_@W7YNeEeQgkkL)MNZ; z!(4wiLvrA2XhqcbrxWB~2VVU>z1~6^TombFx%pG1`-bQb_{pGycH`&!o-Fx$NFEFn z;pw0%+y0)-kZ%=cDH1 zx9M0%>HUmM*0ce9v)X5mFIo{*sR{7hwTH z6#~;VkX?Fz1j$n`)6r~3N4-MmgCAXg{D@Kb@nd|kNcj)Ok3J53)I8nLxMcHSQk&4R zp1^)grUAB>Z0Xi~+WvkhK;ohA2~G1GAhL~CUNYzp<~8bQbt)u zk4a2?YV{#n$YZ^P9FIx-pxLgal#`bdOdBNF4Zo1W$M!Aan6dWn1pQV{o;luP)d#VZ`uNS)@ zDLtFBB;@5~bLyEOylE)2=H+%0se~l^!~$z-y2WPA&VUZ~m-4MwI?+!hCyg08F0m`D zCdb{+tn*@1=?Q3_a;SOj%&Yxr6v5dGvcYj&fz3L}l4e7{NzJrb@N7b7>4QiD4iEC7w6GZXv4EF|4+l~N=UjS`Yr>nZjN;qkC~h{X2RF8 zx%lXnDUAb9ex5CB@&I~RgeWa0toT$=mFL$4i>m7A7bm~K^S=Ln)U(?lqY6KqF^w&!+IGz=374JlKFy_&Sz zk;tNA_z=H@I+l}VhqZ8kJu5A?z=}_SfxOf~-_)Z+U@L3f3-;3NLe2IelyXevaL|4P z9awR(nD!$SnszCaeF}x9-3pq?YUQ;1Kr>g3W|v*IA3^y7+l^562NariIg~ZGLSt@( zgQkRZ2yEv9_m`j2=$lx+I7*{2$HPJUE_4X&3wO}pONX$0+ILaPd$U;EYY@1b8O#v?+B}>FN>w=KfzFA1SMvBIr+H2IPAyV&3LD32dQm5{vB9~gljvVT8{XfKWq+EqM@q=tVU z_~$VMX#I=63fTwrAE1xI--n}R^&0`$>qN%QX#alDzTZ4d1Z`09LcQq^pnboAIGlzQ zwLSyvD@6H(+j#IO^*KSWHsHIOh^hX+Bd$>SLvViH1s(5Ge+6i*|AnAGt^%#~Poir; zYwd-gy}h9K-NbXp5mWuN3-R~6asE{L6yj2x@6oD#=RuzUU8~Xo(0{Z~`?M`^H&z4m zoDkI)0lEV9)6}2n`#_KP;iu<(eD$GyiAMNyyvqMP=$WvWMylSh_fMcTdwT2ovS)ts zed?QyavC2A&%H4|&Ij%5uO~oLeaIJMoYKy4r_-GU&-Z{+dqmKILzKru}g`dh7ad3qT)>;JIT4rGCz5qTn+_qi<)L z^0@HH|J^O+>^#g$GxKr1zSPw@t-x-x7iMJOLY;2KQ^oADXNx_@l7=OX)rL7^dY<;Z z&2)QS0VdUjlR3<_^0TdWYdUtpFUeuaKy#MVf`ZhSELb%byu@V`V6JXSFU-k#2_ile zmS9=-F04aIEOx9tHY3|^VzU@%H!%*3w%jD;p=wM7HmlxnUa8YV9M~}V-v?|5@;i%z-onQ>}#v>-p`{B);`7R zoAs-Yuyz*Sr`)x$;K_45h;8v9$Bwkn2UZitj#c$nzSr6*ic%|EI9V)X%|pixwIn1a zC66LQEnP_FKWbnMD)bUhJ!6SeJ^?$%`hu3o9E%B~@_AX`cDzE*`qnT8?ik2EKkLg2 z3}P{-ZZ*J7_-rkvpxTMg9BZ{F17y%K-IiyWn3|i8RkU)ty42EjwFBTXl%Xh%e7u3@t{2_@cGY}dC;`!j?t zdGyKM&Z_AYDBsrgWr98E?{JO!O<&(Ki)GwX!&C&|99me9w2Z}&ZL+z>PylGF6m5}c zX}C#CQZ`O!0lOw#%g-HPqALid0_r!(mG6;jvdYzk{%v(C^Ko+Zm#1Z3V5eZ#&*%|pcMBAaUv$PVITbJ6k2eQzS^&`hG+vl<`Gq3#?Hdy%IdntnTx zq4CjN^^fC~^Xbb+X}X6??NhrnC!9E5kpsyNs)LRL2pS)){fI9fdD@|!x5LOFnSp8n z@zI(?JE)Ap&j@HUU(0`ayt4PN(OSD6WN2wBs~@lQOG?wBwM%yZeEAHic*I@n9N^Q+ zZoi0cLI%ez)Czt0=oW%cHYZNR^A0{4TJk=XPqX()+_=!bflm4nABD#+;v1a{JE%ZC zG(L)bx&yZWi+KYEuzQf7h(PBz1fd54!wO -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32F_FSW_RRI_F_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x27 & 0x7f) >> 0)); } while(0); -#define RV64D_FSW_RRI_F_64_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x3 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x27 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32F_FSW_RRI_F_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'f') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV64D_FSW_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef float (*pifii)(float *, int, float); -typedef double (*pifsi)(double *, int, double); - -/* C compilette prototype */ -h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t value = {H2REGISTER, 'f', 1, (wordSize), 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF1F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); - tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - riscv_genW_3(tmp0001, value, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ - for (int i = 0; i < LIMIT; i++) \ - { \ - if (INDICE == i) \ - { \ - if (ARRAY[INDICE] != VALUE) \ - { \ - RESULT ++; \ - } \ - } \ - else \ - { \ - if (ARRAY[i] != (float) i) \ - { \ - RESULT ++; \ - } \ - } \ - } - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf("%2.2f ", ARRAY[i]); \ - } \ - printf ("\n"); - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resultOK, loopLimit; - float in132, res32; - double in164, res64; - pifii fPtr32; - pifsi fPtr64; - - float f32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - double f64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - - in0 = atoi (argv[1]); // Get index value - in164 = in132 = atof (argv[2]); // fp number to store - resultOK = 0; - loopLimit = sizeof(f32) / sizeof (float); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) gen_Array_St(ptr, 32); // Generate instructions - res32 = fPtr32(f32, in0, in132); // Call generated code - printf("%2.2f, %2.2f\n", f32[in0], in132); - CHECK (f32, in0, resultOK, loopLimit, in132); - PRINTARRAY("32 bits : ", f32, loopLimit); - printf ("ResultOK %d\n", resultOK); - - loopLimit = sizeof(f64) / sizeof (double); - fPtr64 = (pifii) gen_Array_St(ptr, 64); // Generate instructions - res64 = fPtr64(f64, in0, in164); // Call generated code - printf("%2.2f, %2.2f\n", f64[in0], in164); - CHECK (f64, in0, resultOK, loopLimit, in164); - PRINTARRAY("64 bits : ", f64, loopLimit); - printf ("ResultOK %d\n", resultOK); - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Array-St.aarch64 b/CodeExamples/Array-St.aarch64 deleted file mode 100755 index 46f3931aa6143e3c437560d01afc4c63e1c579c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48056 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 diff --git a/CodeExamples/Array-St.aarch64.c b/CodeExamples/Array-St.aarch64.c deleted file mode 100644 index 728a082..0000000 --- a/CodeExamples/Array-St.aarch64.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef int (*pifli)(long int *, int, long int); -typedef int (*pifii)(int *, int, int); -typedef int (*pifsi)(short *, int, short); -typedef int (*pifci)(char *, int, char); - -/* C compilette prototype */ -h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t value = {H2REGISTER, 'i', 1, (wordSize), 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0107, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = aarch64_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - aarch64_genW_3(tmp0001, value, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ - for (int i = 0; i < LIMIT; i++) \ - { \ - if (INDICE == i) \ - { \ - if (ARRAY[INDICE] != VALUE) \ - { \ - RESULT ++; \ - } \ - } \ - else \ - { \ - if (ARRAY[i] != i) \ - { \ - RESULT ++; \ - } \ - } \ - } - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf(" %2d ", ARRAY[i]); \ - } \ - printf ("\n"); - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK, loopLimit; - pifli fPtr64; - pifii fPtr32; - pifsi fPtr16; - pifci fPtr8; - - - if (argc < 2) - { - printf("Give 1 value\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - printf ("Size of LONG INT %ld, INTs %ld, SHORTs %ld, CHARs %ld\n", sizeof (long int), sizeof (int), sizeof (short), sizeof (char)); - resultOK = 0; - - long int a64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a64) / sizeof (long int); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr64 = (pifii) gen_Array_St(ptr, 8 * sizeof (long int)); // Generate instructions - res = fPtr64(a64, in0, 42); // Call generated code - CHECK (a64, in0, resultOK, loopLimit, 42); - PRINTARRAY("64 bits : ", a64, loopLimit); - - int a32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a32) / sizeof (int); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) gen_Array_St(ptr, 8 * sizeof (int)); // Generate instructions - res = fPtr32(a32, in0, 42); // Call generated code - CHECK (a32, in0, resultOK, loopLimit, 42); - PRINTARRAY("32 bits : ", a32, loopLimit); - - short a16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a16) / sizeof (short); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr16 = (pifsi) gen_Array_St(ptr, 8 * sizeof (short)); // Generate instructions - res = fPtr16(a16, in0, 42); // Call generated code - PRINTARRAY("16 bits : ", a16, loopLimit); - CHECK (a16, in0, resultOK, loopLimit, 42); - - char a8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a8) / sizeof (char); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr8 = (pifci) gen_Array_St(ptr, 8 * sizeof (char)); // Generate instructions - res = fPtr8(a8, in0, 42); // Call generated code - CHECK (a8, in0, resultOK, loopLimit, 42); - PRINTARRAY("8 bits : ", a8, loopLimit); - - if (resultOK != 0) - return -1; - return 0; -} diff --git a/CodeExamples/Array-St.power b/CodeExamples/Array-St.power deleted file mode 100755 index 6965a9b9ef372956b4fbb5adc0aee89a3dbfcda2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78304 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�&CA5jT)Y-)UdzC133zcn$b8rO4$X@?9B(Z_8nc#Q z+N>oEo@)uF&02zKvzEYG0Pp`^{NJ0rAJ1Use_zerCoy;b1bs4dcjh_aJI^XQ`!kqx zusNS$m~$|`(`e5BzNvYQ^&I~Dpcxel-sAI0&qeH`j-vgEzF(B>{R49jM!Bg2#=s9s z?zNL7ceeKrOzfxJ<~-@%^WKZ`^Gp8ygGsWtnfvN7_kHi%W6ynG z(&fhIbImbN>$z{NcXx-LR&D(RV~Mdh7q2s#SLWX=+2_6|HLthE;dMU8p4|TKZdmi8 z?~FJ1k;cq@Oq;pS;NP!zckS;V{6{`tRDUl&xqlaVbezA7?0IH*{x$aHUOe;fBDZTg z`*S+3UCntm*RFhS!#(yX;EmsL?P~aP?aK8kX}EUf8gJA*J;C#@Q$qcX^Sjw=pF+D6 zeLlyy#W7-kPG#mPBQNJ?BQMt_MqciFd?jqikyBN7m z+&aMXzi*5kw|;s2y~Ual=YN`)(P6H*l`GcR`b z;ug~;ZW;V!oc~R~puRD2)Z%wT`0bOz?&CO%Tgbt z;`~tkO^o_}f%e7Em;M!F{U>36QGY~zPXT@F3#h-z?+vU9)CWHCt<;7qFh^77ZMyB- zHEh(d6>U)mD3?0fq5A|nDN{WlY_=zUmHc~m`3;K}-~`Txw^?%sZb$#XYoOIi1>U$( zbhij=C@!jpx~h=uh~zt{Q>&PreE=ld$<-$`w_ z61)X?t9N2}-kh5^e0~J)1K@oKypMqQmEb)OycdG^QY+Q_nSV-cfbH(HfByk-M4mVD z+Y5`KE8{nDo8RO$U+d^aHd2lNN~AVVB7bU{DJ59}X928@#t zGMt1A7%Q09M$7QRzoa&-`=+w#{kmTdXn0t|N6&si6L9VX`(zwCi_fL@1w8WG80wn=r@*U1({W7JgHC>L;FX(~_rV9cw$}92;cwu0#?-aO zBfr1$5lue@^!q_CJoSOEKnDl#Y$%Ao`3LO(-jG`N!S9ED7rxVn?*VZPEI`|m559fX zwPE3i?}f3SN5~I+8v%Rq?Sp;z9t_g*doW9}-uYedm^Zh4S3UUg{keKA?*i;W)?(bC z|In5C<`cd>S<{r2zIK3kQL}*G?if*rZLvPvZ$#UWPqy8KZlpY6x@N&0ba zGl1_S@SVIt#GgUGHFpT_(cwEB<#?BF)sWpDr5KO2hhN*{WB9%h_4}B%htCQvM|#5c zXtmh`=@Is5ynNUmN1;0x`m+H3n#~^k?o~GWR_H;0OJ#&T*cR=<_DQop!ybOs;|z8{zqoD)zz#v!p+=8ayB$7{ z^(O7$({|vudT58E+71EO0qF_Zf&Nzod3&B5mN$t$uZ92J1s;z~8@9t~^bK*~;idQ{ z48IFwmwTnIkGfKB@<`g`KBoQfA8qY)f#!Za9+8%|3h42et6lg&*~X0V#j$eFczw;` z3v8FZz`o#nb!lH{m1Fbjm1m`GY8e9`u7f?WZupAb7E`gtrY*eM7Nz*k5p8i?+X8i# zBRwHoaO`(Wy{Q<5wA9H$trHWU&WZB-sE1&N9;%>+d(oDij&|zKAv^g~cD6|xGY|QddZ*ldTspsv@blX>FOyb#&$8};kv?$HmD2E zeZAw%eVl{s-&H)F3cr0ewdd`w-}+WJzd@+czlDU19aAkLuR5@BF?d;%VkLXLT9NhviG9 z_OA5bd;fru;T8RST%7V>@TYMu$HKBsO7LMGNFe|vw2QV-!-%ff}PqtBp`-=(cW z-`P*ykNWyQvrttC^2-wst$x(if;pAn`Yh_NtN;C;S^v4d=lN7IT;cZz_MQ`6BYg6rPS+`y$Zmq_b0&&&NZ@eB7FPh)5Xnv#mPxdL@pDh#VjSy-2trP10F#RpJ zPN;!2|LV1CCsH9zf7?W;?fsvaz-j(lx38W^3+tnIMf{7EF{t;g_`bNmy~)3E^QQIw z+D+U1^IIDiGLcZJtu>psnDm;O>Mart%Pd>!-x*CN;Hu<;2sj^p3wYg#WKI^g`>yTd2a^$&Do`Lm4tNCc zi6>L3KES%CQmM0mM*-QX=l>G324EQiOc3xif=wgfK75pWKj5o?j{)`}Fg*u&7D4J9 z;NT0X)GP?J_LWpB02oAMyd7}xmuMGo+pkioM+o0arA`9Q!t8M#@Cm@P=(i6yFYBHy z!qZi4eYn^X_-3q>?F8zyuyA!@wOE~BeI=5ZpT&VMr&6sFUsCswRXug?R#d{}$6bf} z49ZUciknJ$t?AYGN}7gYnk0(4p|3NnbyLZKG>t1NiP+8|+)Mu)vI2^=B|*tU6$_Rh z$9)#%Y!BsCvixS%2Fp+5_Q3|fX8BDeLDP+Pkg$9Z_p2y>gyn0s9HHU*v?Xm<&+^r} z{kq}u0LmXj`8*{<$j>LP<|HWN9l++l^jj$z`{{?)VgZQSBb8ce*cWs*H3}_zv-|4n`hiOz>^koKv zeZNVijxoIse*WL`4tv&o!TqPMH4jo-VKPsPcTB zKdZ~9==|q2EYfg}hL>q*fZHU5OZLa5^8wxQSvp^!;pH0EAXu z&6?}|W$QO>FZVC5s$5cO{AVH9E1y-K)$3J$xHd<#S4#Ry{2EUjNvO(G7>3!)SIGLS zFbq|>8OQ90ytF@Bt$%H=Bf5`m{+H7H!( zf|UeT{zf3({{?C5+RHyea#!9{0PZj1$11yW9@7^(QX+C6D|2poC-$f`y+&`Whsr zEJ4D}PA)*s<@H=n;PcD?DEbGK6)y69h9ozFXWo@k;Nm;M(3k&JZx@KB&Oj#rSl(Ks z#ndl=D*tO!ddNhS)B(trK8J*CX{wm!CDupG^ea)d!zCdn_wZWphLc)j7?}U*948Oy_h^@Qd(bwOg_eBOeVk0G<`12|w=d16gpD^!VZ?wB{+8>!sPI_OhUK+EJuI<^?GD^o&Q5p6M(2 zN#1lQde$l;&rFf&&8S=O)1p%1%ZPumXfe{F@K5kVtn|rgqL3_DBJ%~JkOrjLWZo@` zA7C#FPJ8JgQ>T#YONIX|J5k7>&}v8v5HegRKzy0sySn5NQooII@7fZMSur(+s@`?p znE=I8_kw}xZZZ32lB{==k*Cm&Sfm0X!>30qBQq7yUI*QL zAh!YK`YbZmk%BrUdxTv zi~DtPW@P^rNOXjAp8<{QhnKGd2hURc=qQ?}nl>Ru#g_b55b!P#UT+7Wj1yBfA~l7v zN&cXSD?YFH5AmzRXVJ41uVPvlsG?t?Yt|x}F8&qq^_I{}HZyftho`D0Iz$|$n>bNc1$Ct6uG&$XFRRRW?EZapA$2!ZLa(AyWREsAev=(u!G{Vezd~d z3QX0e`!Zb2YjIEqLEy==o6ee!*gV~uVYy2_Tr$68CJKc$-9oB}7$4TUu6d%U=tg8Q zh-M3S$@N7y6fG~Roe5UD1k-ZfG!P-0&$Nn)K#;e*$O1vZR7H<$?aTnmy_$hUz>Jnv zJClS{N=5C=MIb0zYHMND74W5*=$hn-MoBtV^OSuc&ys6V7wTmXnDBjE=BLjDrxoBZ zBh5kgYUbstlbYcyJ3}Z?i=azq+dH)1Dspj^o~a=_&8jO%;vQCwNA(Ytpz7`U*%b{F z6pW*6#U^iCu)fL8)AH9N&2j~3pYLrZ^ zw6d0vUrCO{(z$(*G>@^Ofi)Y-o*8%~;@bB%lglo>h z)zH^0AjNcRG3s2#&aJp2R$>@Sg=gySw}Eww8}RF~-Y%IcELi+6d zmj%tkEaoi0{UceZ&`^Y1v}J2|QF}bO=u@4M7*wi^4UO+y)ZAb*eQTsbTA`vj*11S+ zpcX}A4XvGx5h0*GXxE4c?KVcJPC7{*`(vg9_X%O;x!uz$^Q?ULr>wj(_l%}I%N_GG z1*AK+f+@ekkuZPp%sj7^HyhRREq@*+eUCeTWu8|;E6*=sB5yV!XcU^ivILA~t?=jn zclQ*_<$-EA3A)9*(|v4M_ht*_F1Mg|qja;8axY3_$1><5Gn7VXKiL*vl;~(!)C>bO zR4l2y?mBz2A<-$YgY{Q$^`mH6<>IuvhN6jfTP7Cnh>K8&4u0K|P*NnKv1OsA*7m!j zu_hZ`XG{|0o)NDclxq z-6htwHZ5Bkx~;vVQN&srWzn)w99&V2J?Ipz?XhNmV|(Y$*2r)xv4q0QLbfjx@~1PF zh&IO}jj~%1XjzDZbMZ3W?|_m`B1J6R7Ln>%vv{%I{g$v%g~V5`P7}c_nDUvZ4tvupFL_k$@^qZIO=VNJY4{ zwW6Ut26M)e31BkHy zY3h*d8^g)4Hha2(5%zCv6`|Gb?X3u4k`>jh17s-D9z#nEv%|QqB_EUikhZyUKh!3M zwT(=}b;9%xZP@FU*u!fY9RLOF7)pklhwDXS+TS)wSJT}ZE)TOaRD=lCZVt(iAL>j* z8aan0qYV`uaES&4zm2$bzR>~a|?6SPxm@Y z!i^?HuF%q9A&SvGGFU<3fk@N*3+j9Un&PvVm zgOT)w!aRoXd)@63juF8uFUS=yZ;sMZZ5_n6Dj-NMa`rZussKk%%f49Vs zj`KXzxA>$j(0Y9T2@oKK>&l&xq!r!yqoulW?g_?fW3`Ktw zd0sb2yh_`DH{`(Iq51Ud@qR*AYSQ>8igbUZf8#(X2cLtQe&Gg1e;j#UM*ye0W{5yW ze0x&Uzj}kB->3uVHzi)xwg3JQc4p5=-Bbi|qCI-Z!x|I5&u-_Ag%Unjk5w&>OL zhGarCK_F#PZ(9hEu?fw|$w7WTK zT&wvk(|jJ$arM_49|WHA9@2cYS;RI?e`2<3_X(}fu*N@Esqk~)O1$F0vp<=B*sbY< z+ZFwJp8et4Bk?M2|NTQvU$u55{lmbspO0nOR9yfu=HG~)1! zSe!|9;a!fV4xEF88avzCcA1veZCWcEx@k-GE$c!iH_VfVFN$Y1xAhfUla=zc6@6`4 zf?aGPwmuSzbcE3s5e+z?0b*MehfK(}wl^s^s7-HvxAdDxXvG2?V$w6v&}7*S_5Nz>gO(d2l#Xp6Kp#CMIuN!e%|qBsu! z+B4)>`=2&d-%`6Ki`e00dvpZD5hp6@>?st&DR5|AO-T86&Dt%Za@*!Lm73j>ox>gi zRkyXr)R`5AgO=d6m5mpH|5xx35McI>M-NpYFhI zD6x+RTYbbE9Ea-DJvoS*w?>k+JlR4~qCM0Sjy2-gI^#4^`r8OLBTvQBP2X~BNJb1a zPvxQo9a0!$qV2KG8;13?#jdpKwQHq3I}-`rI}RwJz1Y@tx~Z+KpB4e#-*(Fy9RYR3 zu-DS#%!W!2avKh|49P$l+M2X=bltWPcAk}qU2VzmPQYY`f-NS60ELH$qEbFGt6p7O z!9(0ioTOK_gc0Z}8+XM}S;1t7D!D7tk$^@zN&M4IAGFHf=M!#YYNTDOr-A(@`QtH9JxIKH0Nu8^2%IeoAr^GM)5hIIR9b$vj2algxp%QPlU`{smc4RBZrr|X+@LO^+aPJ#4q zrv5gdgzp%e{+sheKzW&yBh!CFXW$M{@ttLpH|LIk^71P%s{a}-nvo!>sc+6Fx&G#b z(J3#}ey04NLMiL7R%GdOOq^%RE1(5tmZy7}^*;?9N%S%}ecsut5$1dZB=YiWXuuvM z?Dd7&7t<+u-KK!~^_zr-p9LII-<+TF9S2+s6-fVTwWjm5FY6oqnR8Y^d3}@4VY`g{ z2K68k_WI^L7EoT#8A1&++y5f)_WI`B7EoR_8SQ7*e^S>sWafO=|Bk9}_IoNfY(JCd zzKrdg`sN(CYJ&B@g}OAgsc+7UgSvhnnd374Vf1JEbpmDf_S5Ie`UKVZuVlg>&Cl?; z3n->d`>>>BU8U=Hv5xIB^$dI#W%l;X{<%vxWcq1Xn0hAvzmTxEZ}x5bb^SU+s9|RP z=YePYnR1%?GcxLH@iliLeyZzdkclIj!fz^Qf=qc{&r!cmz7fRNaYu5_U?&E1)IZ}@ zl;1D|OS8$WpASSPj-(G3DQxqwVI_x5TE0C^T&Dicmnce}H`p&z-@uO`VbXTGd9xID zT}EL>R+Isei6fu*WeVGCXNq*D{z;XgB3a{{uHVne4Oc1dPvAEGW9BdZ{Y!?5fDz(! fscOI23_OV)-B+#;vekd}qpCh%eYIa1S@C}Wt?;%2 diff --git a/CodeExamples/Array-St.power.c b/CodeExamples/Array-St.power.c deleted file mode 100644 index a90192b..0000000 --- a/CodeExamples/Array-St.power.c +++ /dev/null @@ -1,909 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef int (*pifli)(long int *, int, long int); -typedef int (*pifii)(int *, int, int); -typedef int (*pifsi)(short *, int, short); -typedef int (*pifci)(char *, int, char); - -/* C compilette prototype */ -h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t value = {H2REGISTER, 'i', 1, (wordSize), 5, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x383F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * (wordSize)) / 8)}); - tmp0001 = power_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - power_genW_3(tmp0001, value, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ - for (int i = 0; i < LIMIT; i++) \ - { \ - if (INDICE == i) \ - { \ - if (ARRAY[INDICE] != VALUE) \ - { \ - RESULT ++; \ - } \ - } \ - else \ - { \ - if (ARRAY[i] != i) \ - { \ - RESULT ++; \ - } \ - } \ - } - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf(" %2d ", ARRAY[i]); \ - } \ - printf ("\n"); - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK, loopLimit; - pifli fPtr64; - pifii fPtr32; - pifsi fPtr16; - pifci fPtr8; - - - if (argc < 2) - { - printf("Give 1 value\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - printf ("Size of LONG INT %ld, INTs %ld, SHORTs %ld, CHARs %ld\n", sizeof (long int), sizeof (int), sizeof (short), sizeof (char)); - resultOK = 0; - - long int a64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a64) / sizeof (long int); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr64 = (pifii) gen_Array_St(ptr, 8 * sizeof (long int)); // Generate instructions - res = fPtr64(a64, in0, 42); // Call generated code - CHECK (a64, in0, resultOK, loopLimit, 42); - PRINTARRAY("64 bits : ", a64, loopLimit); - - int a32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a32) / sizeof (int); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) gen_Array_St(ptr, 8 * sizeof (int)); // Generate instructions - res = fPtr32(a32, in0, 42); // Call generated code - CHECK (a32, in0, resultOK, loopLimit, 42); - PRINTARRAY("32 bits : ", a32, loopLimit); - - short a16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a16) / sizeof (short); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr16 = (pifsi) gen_Array_St(ptr, 8 * sizeof (short)); // Generate instructions - res = fPtr16(a16, in0, 42); // Call generated code - PRINTARRAY("16 bits : ", a16, loopLimit); - CHECK (a16, in0, resultOK, loopLimit, 42); - - char a8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a8) / sizeof (char); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr8 = (pifci) gen_Array_St(ptr, 8 * sizeof (char)); // Generate instructions - res = fPtr8(a8, in0, 42); // Call generated code - CHECK (a8, in0, resultOK, loopLimit, 42); - PRINTARRAY("8 bits : ", a8, loopLimit); - - if (resultOK != 0) - return -1; - return 0; -} diff --git a/CodeExamples/Array-St.riscv b/CodeExamples/Array-St.riscv deleted file mode 100755 index a53c8cb343de46718a54e0f720fbbacecf9a567c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33256 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 diff --git a/CodeExamples/Array-St.riscv.c b/CodeExamples/Array-St.riscv.c deleted file mode 100644 index 6b54d58..0000000 --- a/CodeExamples/Array-St.riscv.c +++ /dev/null @@ -1,822 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 1 pointer, an index and return int */ -typedef int (*pifli)(long int *, int, long int); -typedef int (*pifii)(int *, int, int); -typedef int (*pifsi)(short *, int, short); -typedef int (*pifci)(char *, int, char); - -/* C compilette prototype */ -h2_insn_t * gen_Array_St(h2_insn_t * ptr, int wordSize) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t index = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t value = {H2REGISTER, 'i', 1, (wordSize), 12, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1F1F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, index, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * (wordSize)) / 8)}, immValueZero); - tmp0001 = riscv_genADD_3(tmp0001, a, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - riscv_genW_3(tmp0001, value, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -#define CHECK(ARRAY, INDICE, RESULT, LIMIT, VALUE) \ - for (int i = 0; i < LIMIT; i++) \ - { \ - if (INDICE == i) \ - { \ - if (ARRAY[INDICE] != VALUE) \ - { \ - RESULT ++; \ - } \ - } \ - else \ - { \ - if (ARRAY[i] != i) \ - { \ - RESULT ++; \ - } \ - } \ - } - -#define PRINTARRAY(MSG, ARRAY, LIMIT)\ - printf (MSG); \ - for (int i = 0; i < LIMIT; i++) \ - { \ - printf(" %2d ", ARRAY[i]); \ - } \ - printf ("\n"); - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK, loopLimit; - pifli fPtr64; - pifii fPtr32; - pifsi fPtr16; - pifci fPtr8; - - - if (argc < 2) - { - printf("Give 1 value\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 - printf ("Size of LONG INT %ld, INTs %ld, SHORTs %ld, CHARs %ld\n", sizeof (long int), sizeof (int), sizeof (short), sizeof (char)); - resultOK = 0; - - long int a64[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a64) / sizeof (long int); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr64 = (pifii) gen_Array_St(ptr, 8 * sizeof (long int)); // Generate instructions - res = fPtr64(a64, in0, 42); // Call generated code - CHECK (a64, in0, resultOK, loopLimit, 42); - PRINTARRAY("64 bits : ", a64, loopLimit); - - int a32[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a32) / sizeof (int); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr32 = (pifii) gen_Array_St(ptr, 8 * sizeof (int)); // Generate instructions - res = fPtr32(a32, in0, 42); // Call generated code - CHECK (a32, in0, resultOK, loopLimit, 42); - PRINTARRAY("32 bits : ", a32, loopLimit); - - short a16[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a16) / sizeof (short); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr16 = (pifsi) gen_Array_St(ptr, 8 * sizeof (short)); // Generate instructions - res = fPtr16(a16, in0, 42); // Call generated code - PRINTARRAY("16 bits : ", a16, loopLimit); - CHECK (a16, in0, resultOK, loopLimit, 42); - - char a8[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - loopLimit = sizeof(a8) / sizeof (char); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr8 = (pifci) gen_Array_St(ptr, 8 * sizeof (char)); // Generate instructions - res = fPtr8(a8, in0, 42); // Call generated code - CHECK (a8, in0, resultOK, loopLimit, 42); - PRINTARRAY("8 bits : ", a8, loopLimit); - - if (resultOK != 0) - return -1; - return 0; -} diff --git a/CodeExamples/Array-Sum-2D.aarch64 b/CodeExamples/Array-Sum-2D.aarch64 deleted file mode 100755 index 2696a911a59ff2cf42f7e908bdd9b1c704fe4397..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52312 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�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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_GE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int(*pifpii)(int *, int, int); - -// Sum a 2D array with a constant -// Code specialisation on stride and constant value -pifpii genAddArray2D(pifpii ptr, int stride, int constant) /* C compilette prototype */ -{ - /* Code Generation of 22 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t nLine = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t nColumn = {H2REGISTER, 'i', 1, 32, 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0F07, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - sum = aarch64_genMV_3(sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = aarch64_genMV_3(line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = aarch64_genCMP_2(line, nLine); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = aarch64_genMV_3(column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = aarch64_genCMP_2(column, nColumn); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0003 = aarch64_genMUL_3(tmp0003, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((stride))}); - tmp0004 = aarch64_genADD_3(tmp0004, tmp0003, column); - if (!tmp0004.dontFree) h2_freeReg(tmp0003.regNro); - tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = aarch64_genADD_3(tmp0006, a, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = aarch64_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = aarch64_genADD_3(tmp0008, sum, tmp0007); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = aarch64_genADD_3(sum, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((constant))}); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = aarch64_genADD_3(column, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = aarch64_genADD_3(line, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, sum, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -int sumArray(int nLine, int nColumn, int a[nLine][nColumn], int constant) -{ - int sum = 0; - for (int line = 0; line < nLine; line = line + 1) - for (int column = 0; column < nColumn; column = column + 1) - sum = sum + a[line][column] + constant; - return sum; -} - -int main(int argc, char * argv[]) -{ - pifpii ptr; - int in0, resultH, resultS; - int constant, nLine, nColumn; - - if (argc < 3) - { - printf ("./%s \n", argv[0]); - exit(-1); - } - nLine = atoi(argv[1]); - nColumn = atoi(argv[2]); - constant = atoi(argv[3]); - - printf ("Array %dx%d. Constant Value %d\n", nLine, nColumn, constant); - int a32[nLine][nColumn]; // Create & fill the array - for (int line = 0; line < nLine; line++) - { - printf ("%d: ", line); - for (int column = 0; column < nColumn; column++) - { - a32[line][column] = line+column; - printf ("%d ", a32[line][column]); - } - printf ("\n"); - } - ptr = (pifpii) genAddArray2D (h2_malloc (1024), nColumn, constant);// Generate instructions - resultH = ptr((int *)a32, nLine, nColumn); // Call generated code - - resultS = sumArray(nLine, nColumn, a32, constant); - printf ("%d %d\n", resultH, resultS); - if (resultS == resultH) - return 0; - else - return -1; - -} diff --git a/CodeExamples/Array-Sum-2D.power b/CodeExamples/Array-Sum-2D.power deleted file mode 100755 index c8addeb9d750a8f9c08b247293f482866053ef8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78352 zcmeHw4}4VBmH&M+lVn0d7$9O)G=qRm*d&BM#X&$OAxHwKS%FG_tG~&R49V1F5+@TK zY$5|oTkPU)(t?ftu;7-uxIcAcm;IHxc8y)uMVEGwA8n~iC3LkrqpY9Usttei{l4e^ znY>IgNkCHh{66o&d*{A$&pr2?bI(2Z&wF{ZdHL$wESkpDVPRJ>x^vr^gK%!T;Hb9 zrG9|CJ_Vh~qr=Isf|in%?}TcoT=9b<1CWF%3gWwDeaY<7 zBjs06wZrUs|AqzgXV=#(m|xV~STvXFC0U3s(X6;*9j=VG^EjRo7cy@a&P<%?ILG5O z9#oxb0^&nF({Pe*WLs)`;+KJw4x&*fM~w19WhPY(CZ>9Z!Y=_{`J%DZswDIalHeEHgRH3~)J&J^IxlX5{y=CW ztM!GNytTe&|3g03&=hP8`Km*#!CPP7Sk0P4H7Lk7J{a_ee9Rka^fQkKj#TYw4tawi zPlMMVV02F|wScWyT~WHsGq-5Y%^<67Xbea)4`j0p_-DLFCJqh%HUKI=|4zqaXj%)a z=eh7DUG)E(aIg9-W#t+0$`1+eU>45mDx}GG)RAMr%dWz+oCdt=qm+?nz#HROu>ns$ zs1BC_PyIk0ZUf#Zf4Koq{YxE{2E4I9t~cOSpQ18V20Zmub<`Q~iG5em7-0@8>2q({ z8hhIMNSo6Zxx<)8X^X?Xm~Ad~J#DeKI+)h?ls>Hw=qh`}5@l@f>`eA)$&Yn?75GFS zwX$-``{+IatJpLb%0!>G+FPA$FmK{d^{*eMe#*}qA-{ZteCG)H#UtcbjgX%+LcVK+ z{JIhH9V6sd4wJ9iFPxFz`gZEHFih^+f;OZ!K~L#(Ml7)lpXwAQt8nte?aX8aNTo8- zp^>aor{bsXBU?7OB3o`;$a3=0##?VEyd$zT##liC-IL#tZ;|huM!nRY)8J?1FU~>! zQCc-L|E;b{=byKRZrIiu%G%btOWPK&E9a8yBAo`-2R$Cas7G?ICb@g{SI+BtDGe=E z+qc{p)AgS$bv?XtVN`$WeDT9?EzV6M$y$4wzH}os$GEkpxlK7S`e+dCIJ z+0qUK&2qpkBp2Nye@jzVej6Z9lRbL$t?nBkTX@yNj9p#E{KRm`*S`MVjHrAEpExP|J;V_QqAWc>%yX0;Js*Yg)1NXu^vubR;o zUbC$2Da0D0`7|wmos;Fmj`;o{^$m-Uepu~#>b!_eWSy+U6ViP# z+v*-nzY_HMZIzYzoKDpnMZF#8ggvrR580>}xHgF+K4fpe4oXv-g!G7e9IJAjl{89T z)po1FhuUd0@*3qxm;6*419niF>g_i=v zmdFQ{8!~%4d4FeB=+mR_yUIq2FZr`GuD5gH4767r+8($8eUbc8m9emjn8p~r1| z>(u|Jx4AFEACkvN(UznKY`3NO4w5~;O~jt19V9RL>rgs#dZ}|?x#)+k^1-^39V(Nw zi_uq~E-mDCdAhWqjciZ%d4TY}Er45C`8bRlTiqnnt7)?~k^RD}DtLb(TO`CgmMq>W zTNESSx!4|@9@0HVv1Ds+{w61*v5Qsh!M_C1pA2HGwvYj>Z zNMn0l6bJIy=4gtcEX6X6yCu}VIUiNKp7~ht)%7aZCo)a-inh*w1is3w}H_bk(vp0#V9v)5`%(WlZ2_MxAhgN-TOiSz}w z^btS$$PT2ZY9bxs_*2_0njTHna${MVCsu^=VqBQjb`<3?hj%gdOdmnJgboRF*fZ@! zqX`VRCkF#eIx zMB&4vhirfMILK(EYmjtyZE43zsbdu7e~U6s=zfxIDftc3WQU``t2z%Mt@s{9TG{Pc zq~8U7_Wt~J)R%W^0y0;=kK)oe*yo0bz`bP=kopnjk?oE$(U)(v8S}ot<5@TF6ZtV4 zOXqR8drK+cIP{5k!-!4XPA8Zi?P0mGDD2V8PPyJ+Ky$HJpPi+jb+C%FIWqn?Sy;K! zw-+)iecv|ddjfc+?-8VxzTHTZzGTw_NDrxRtI&7WF#3`$^41GI2kMKt1xHXpjc(}MleLPt| z{)IL+{kX~yzk1LwDSo*TqmLWn*J0pQ-+c*b)%UuPR`Hs~xgq1%)X~N3fpKf>;#Cy= zzU9A%k5}ttzS22aTo_HfdhN{Ri&t%u*X4*;b0n`THD28>=UH8tXC1^ms~hvI!ZIlNk?;>m*m`q#^zVS zo8~SD&=-D!G|gT11F!1bjkMz1j`ZuGNt}}~Iet^$7`ktd&esw1V+S!Vc4J&T3_Xty zGbaflHYz=6PNnpC)}Y5;gC0Aj9;Dy)WO@{ceoSNXrS#Q{k^cZQZ?Lc~bmUeLd5!<0a&hc_Su6C6~hmV=lWWMSf$zmqigXU7N!k2#nU;Y{V zDRGXs>%T-@s&6IZbu!6((KyGeki5wMX#Ryc7oUd>H7_F?H7}#InwKd&%5+d#&C4jQ z=4FUe(e_c!%Z&R4v^J$Rak4c@(v~rS2N{Wl=?r-Q79I)BF(T@x&yJ6;7$p5OSlj5lFC8v$0wl-@;jyg zb^_juF_dC2XgloMW|vb_`=`_RJ{#(eq3#&!j_qK3qC2tgx|^Mf?qho7nt808;-!k~ z=Mv(&CVBUPH_58#u1#2z{t9Cp$&iCJsnV|pI+2W6$MHE1$xXV_97okja~#FD3u&5{ z5e?08XzU%dChZil@f>7MjQ?s)dMnCZO5DUa7qesC;efr!R!%MXS~M?}l`B1aA*<4p z)}l&JT8k<@X)UVsq&Q1@sq+wynyah!{Y-w`er4!ch51XOACsP!;>YBxgZiuVWAgE2{dG7$E*c|0 zuEV@X=^d5*m*xw!cc$9+sGM_l}V`sG-YEq`ZpYqIMlopDV@v7Od3YV1~PGKzUG0#9QXjooj`bQjXp z|JB(2I?{t;!FJIn$gh&c0@^#gl(C!UhofDy<)rnm6?zSNQp{6&(%7x^q_JD+Nn1cI^3gV$Xjso}GS^kJsW|uO|}r)t|wbPW$Dwe~&$X zz9#F$+~qNpp}4jKYte5ZO@1B$o_J9@g!FfjPTV(&xM{o^-M&!-<+o$crk&;D`GF_4 zcbMm!J^Y=a4U12}AD{W@@c#IS%vX9RoAZ#qG#7geGJFd%kUoj~MxPuJb&;$i&3TAM z&3P!T<~#~da~?{o{TWKD{TZ~|CGF4rG2ijYUOD#f_&73Ixq3%(EqsjjG|At}k*0UB zXuo4I()4#1c$UQ9pXx*VF)bI*OgwnLl>AxAfecno^IY0@Al?)g6mQz^G4d{!ymPR3 z=LGLO@Gc&P_j>St6a0vW6TB1OsVq4r`Wej^RXifP#CIyMk#s}7o22HIzd=1}Ua9K5 z=ywd|ypraQ$@Ye5e>2(M5VMYcygdqePoRxP^KPYM+~9XBuPD7QV!XW=y>rqB>#gR~ z)ZS`7{du*wdyLxKX}`kt9;5co!`|;n8H;EgLGR$Hbp*AyT1R|d?Hw5-y^FE;tMsP5 zU#0hDd-rgZ?}}f_-u}h(=W?u%m7Z5*`;Jk6roG_d^rrEa)=QV{*YcUhrH)(KW8~NC zu{WHkw^|=lfByef@2atWm-q_l&uTqv|3kGa|CQm_AL%k*`FOJR2l)%FKZg6;hqi7} z*E#qQ%`KDhx*&Na?%x`pThEcaXihyGuhIPN!#ghvxhN)%v@RkVwJxHxS{Erit&1qF z)!M5j+lNbC4?q6u9j!%Em}8-~4(dhjy=m))@BIh`-BQM$7e7I*m z#bfk5w0wy7Rjwqx=Zulwm4^3KXf98FZq!??)kf3a)TV>l`!o9awlVVap`P)nIqj9; z=L^QDy@z_ncO~h4^BC!U#XsXq8U3E)#f)QD{4>5W>fdTjQ-?X^x&y<{A-^c|Rg6ov z4xw>zr1x8%`Fl~$q{`2~~LK?d-=I;uV$xm~)q336# zd;UqjGTOQJ<@me8WP1ED+ClwYVJBiu?C*w;HLuD1%MojqNM4sC)_m~1kek}=N{kP4 z&Wmqnwc7@M53SSI|6RA;Ht{X99aiS}l7;oQ<2h>Qow@kViF4sz`8R(1@r=?h{`T*2 zdd^Dk1~>tC16l=L2jS^&0jb=xvfKd)F$VCz9XurYz+RjW@;RS_fHsr^9p}>xNPG^< zaz`aRAz=^lNuDE;5Ar#mh{+E0td{J9za8nw0t6lBlMP7nU_XtQn;{|oE`;CD zM?Uev-$`;l$me|W04D$sI?e~rqB$RzEa#T6T*6A^6Q9MB5Ar#mGC&9LpyPa21Cl&z zWx0DKtdX!D`NU_vUjC4zKO*6A2~W!Mhh=%> z^YTY!dC&oi<-=y?4XB)!cd{2)`pY>Tizvj~4cJ}++v zB>RJom(P*(P6_iQESBY`%JRtP^3RavLC4F_m-LGzER%4xEbo%#k2oPq^P3uTT8lbi2)i7)*cHExtP@=VFih ze?aq_uOObWs!s78G|+Ur#J98}F7($WOZ%pKcVS$(w@Y88>hFs4cP{Lf`W%M5)W5p` zsb3tBdL6_)_4k(mUHCg^(8=#aiobL2vgF1<6YI8kVlHh@)UCZ7E!R#(EAcML9DIA` z9n?+oslWejM}2Q_9AccT`?!QBC45`Tf_yH^Q7H@PxGX0C8Ds(709lSe7SO~_LKX&D z?2rZT$VBPAmha=+XkSi{r4#in2X3!zvkUQi0Iz3RZVWLz_7dLJO60ZhB`T8}+mCkX zvSD6h(_Qc1itlG>x%}H`4)}Zy{vMpZxA+dmQHn!RsavmveG)ROusia(u4kmKpyRrJ z2uS?_^c{OiFM}=V`)Q#m;yYj$C?Dfp)UqeqYk4`^XE_yRRvq8^oZj{?C(!;}j{bIN zLj4s|Hk(!UO$oCloGN8QK9|jI6@4`m_v8}}z^P~l&<(Ji&6*nnO)T5$iA_a2%s@L7 zpdIFGdgS^K^;K^?H_#`-kmbj~Q9EG#8^G%@+5uxA-l-YP>xCDGZilI8hZ&mZYysL~ zzHEnk!C(2m)7syki>0nEsjE}!Iz#H3Cv`0Vq;>#(M`W0Gn2&sF2d8yUG|&2SwAgwo z>XPlS1b;X2^Jj%WESB|_Nw`|VwJ1;h5c%BZZYc-oxXsG}JHem6gINi?laK938!U#+ z%V2NtiLJE?f2?EL*(O$UHq54-jWE$)$uFrazKJcq2ddG#WZ28rJhA;~t1h(FL9|sj z`pi>U2OpyL1r6*OgFRztL+q41>D0>LJkAU}a@IDDY$cIm240^=) z{Y0#@OI`#$`RoVMPV1#zswAwFuu0kp`P@$TNIQX!k0UjJH1Dbh?12vJVV^442jyc; z!`KHh4bb5bbT|T;jzfnY=n#btz0jc#_Su3pG{(U}I{ZTFPzW6^pza>YD7NU)ui=@}eDKb(2@Lmo3 zyoPsuF~$#Sn^~xX{Hx<{`{O~oAs+0N_Sp};$v*9XG#>7h_UXhu#lGEuw7#Iev`_X! zieK$kv>EIKKC%77*a@-?u+x0lU@>GXgB=pb(NB&K9p|9`SvTTbIpQ4IhGGHWAf0cM zIzRc0zG~fm;TO+JJr79ul7xq(-pJ>AcS*fL$Mrra^Sc2_-)Euk0qBeJu|vb?OL5p3 zcSKBCikLDuu8&WmFUkyx>tFkufn&*bj3xJT9M)J;r=t>{kg!MUfPAjw5ve2SxQ@pG z$@f9u5k`9?8*@)0pJM%C>z?RQ>&wv-)>F|Qs~B^=J^HHH(*tFTK(?QA9M)}8mNOE5 zDB%V0B)>yGmn|w~109#GSLXKtlKtO?{m;PuC?C5pjQxj;`wX$gI9GZU@8ynmev^`* z<9_J)!T0<77PIw_wGNw@XXMy~jtr3cmdz&Dmbj+}mukYq(hQHro?D!(NVl$WBEs;Cns(_w-fQqa4*m zv18f~^;P2s@UGxKa#+s6JJH|py~~CDb<^A(Yh$VZ3<(P)oDV&y&5_UT;gt3O9k)jw zAlU=-!_EPVDIYRUg*|4#9tE(+e4A%Wc+Cp_{pBD34C{p?vbm%zZVAgJtOQSz4f$NQ z#ZorVaoNfMNjA_AJ1<&|e3H!t+1!w=9I{o)wwejKwhw4$VXw7PhI=Hek+2@TNG9ZS znbu30K*wdO0wkG0KWzW4Lq5s07BbxfnQ9JahJLx|x2?MVs;d}(t3&DVyw|aItyb z?&)tgEcpKR41AMZ{2d2C zdSRm`d|PBR-!X5}UpX7rPoItG+PUrev~%rx$+=G5dv343<=lS#sdHWWE9VaCr_Xik z+WEu!wDU*xlJh5Y@A)2m%X#{35Bl8?ZtqXk?*#Z;_v7!K==U@B%5UI@@p~#*ADzYh z7W%uy0{jire#nVuO^{Xm{={MILr;5L?B~*V%)j`ANE01>|6kBfZ@X90(BDYaL4V43 z81k1G^6Of{S5x?e8}`@r;sCneEMyL z@T$BvUAHd`v)r?k4li@Scb&KN6xkozSM-I4@caPZ$|OIsw;cq{KH$3~ZOzp;YznU_ z=j9{u@>5X0=N7_;m*o(zMaN$GL+h~@u4&6IO=~;$$}d_cb$<*$Jk}as^!wKAC+wh` z+}2Z6j{0gJI*j^o^7;<*`pO^bj`O}2{HhiS-cym@yXe^I^R36;xL)u+{buW=o^#-R z9K1hj&Hh{BeHD0b2k*aoDE!q4ZTpJ;@*%G0nu@k#6?xp3C%~ST)A^g;zKMQQq=bLx z`zsYCZM0sqB9Fd(Pd>gKZBBin26jG-KCzK(EZaM$ui7=|JHoa^Qw17ywDPUJuYI+K zzHnDLzG1wwZ9Cd%19aSovF=#KO>NmLzrf|lUYQ4-DmtjlcC^g~&}{_Wv5GH% zM#!rAnX1=`dVlnos26qeenfRseef6l+W@WTNA#N+N=c9?H%p!P zT_NYg`l9gk-K~{;^km z_3R)MGe-PU*q+j-Ep_lQ`mLsnXl2!3v}ON~sH>Zy1 z`l`b?58>>_`4Y~9I1k|L!uc%D{W$mG+>2A`Ms-m;JO!P81>ZyURfr4m-;FTZXhwth zNxSa*1&jm*)R=|DW;5qh3s^k2#(9hLE?=#4W;1^9ZDtKeGp7Iy8UE&wFX-gI%;ydH z8w1XbUVpt$()l;mw=~z?;*9@kIgToCj(W$KBpwz#phB zaIRTb>huSiL&276UP(Xgfcn1Vt-mu!($02z@#}zffDf+r1ppopAn2>TBiKmy-uf0_ zMMHzA=dR@|c;ZVX_=Oi7l{0H@fyT3ER?nVUBmQ%l;_}?SZuMy7iPJB;z4D^y?;Z^` zV{!g>T_pXQ(G`gEFI};GG&RKOOUlYFioUdDH01sIt{Ij2`{{50(x~_s&7RrpTztoB zf53Mu;IhX0mWBXQ%NpT(-ayC+2W#=&8u!nVV9>kCIkP4_v!=*7kOkoSEO&^&EtYFd!bvu*Exd{T{%a$8?N^=`ntPF?Q- zJOW7FwSaz22(a=A{G|ZkKENu#d-mx1Ho!~-iv55eB4``|T>Ff!p8?$ag04HP_-)x2 zb$vcy`764PzujT(f7bO@!1YH_FJR>{T|Wd^@M~R<0zOvjPJF2A#eg4vr0e)w zC)R#W*LMO|VuUyh7zJdI(*Ygn&>p&r*}^5-b(tE&?|R`k6*2olnHtJ0O)p`ksU>8O zVw`8N5~}C;tjaxF$@ttgD1^g_6LWm#`W9pYWVdBSw237TbDHXYnh>&1faWBXx-F|c zPGj+NBC4koXFF_t1dx?wxj7G!&D-T5(2I9LH<4e=^H+*GsQd|>^~nE_@^8y>D=`{D zLiv3--DtaglwT(G@bs6bHa~>?D#|aF^;h=ilP}oN<}-v2m5TpYCI9un+u;Lisl1{7 z707o26-NGI-ZhBkhB!?(Xzsxe+C>FTzb&l=oQ8CL zoA^B~by2pwL+C>F*x+wf$X|_#4`k`?mnFrbWXS`~_UCo|SwUl{=lVDee)pI;eyHmg z=*LZs?P`4?E-&6;WKsOsXCGu5P?x2N3*-cPCum-J8U1cNr!m;ZWmWPV1WgwPiSgDt2C>L`{QQLg1LdhJF9H>2jD^V+?~~H0gu0&^j8zx9UT+CmG$lMJ2Q7>JT~q- z>7Dk+)1FBEUn#q7Pg=ig;an`g2OH{l&w>Z_=L1Ny<>-?{wv6bO?a@|bkq=g8u@$K$ zr{4PY$^Q_2y9Z?=A0w7f8S^kLU|PVmfN25K0;UB_3z!x#Enr%}w18;=(*mXiObeJ6 zFfCwOz_fsA0n-Ae1xyQ=7BDSfTEMh`X#vv$rUgt3m=-WCU|PVmfN25K0;UB_3z!x# zEnr%}w18;=(*mXiObeJ6FfCwOz_fsA0n-Ae1xyQ=7BDSfTEMh`X#vv$rUgt3m=-WC zU|PVmfN25K0;UB_3z!x#Enr%}w18;=(*mXiObeJ6FfCwOz_fsA0n-Ae1xyQ=7BDSf zTEMh`X#vv$rUgt3m=-WCU|PVmfN25K0;UB_3z!x#Enr%}w18;=(*mXiObeJ6FfCwO zz_fsA0n-Ae1xyQ=7BDSfTEMh`X#vv$rUgt3B(Z=l50#yGugQ!J5@t#mNo5X7j+ghX z&EnoB@0%>*{-aOzMnZMV`xKd9Y!msZ^1esrkCXRbmoP)Z90{+IPywq-FbkK*BJZ72 z@N9XXCgIf*=B0@Gaoa?w0x3WE@q0Qda|M{WGMso36f|$So<)16aR@ zi(qkM`THLW3T_{S{QPWDjIdy!+! zne3+Y_vvy?_8I~ax?GzbB+!eCZQ7(C0HkKx-n6CbNTqqf%68J0^-s8AX%Eufuf?4$ z?KIuJCGPCZUWE#6r)<{OK?%)Vs5AW=NKZ#%+*~BAB;+jIS?so}2{>$%05bkB^3rEJ zzD6Xsf@jK9u5jjkVCYEwfjtbO@sn_qdLX3?X*T{zP^JFExHe+KvMK?1O^+hMYZ}ic z*a_<(%*3fEn$?Na1Up?Fe@(~`A)n(&x;lPH$b;aU^%IVytK$eEj}!8j97$KlX>G5kYJz7PBQ`coFim@es!P$bsHtpeoIF*#s)X34{R`!#iM$+^ zMdqAfr>mnAmx(kSWPOh#>FRinkOv7#s!y=f)$tQTZXo1OIg+l9UlQ^L$dUCMj-;#O z3?aWmlz-qzx;iu{J28q>Rwhyt>~wWZ;Yn&q$26XNl9B~H`2$Mc%#;60$x@y?Ny*!J zl8o$F&y%FBqnao8Q!>DlKc?g+o;*g$Z9Ms3l>956yg1QeI3ZO8@R`3 zZbWUiv|Kwi+xQ4&OqX=XgrT#S67u9Yp1u=h(|(;XjqrJd ze=B1S(k%T6TnNj3aso>y7L>#9(^xt+AT=Amx3bKgBxTwOJ9)_Xam4jh`hRjE(kUp^ zE7CNC49g)9U*)uyX6+;D^T@ZCWl^7H;{zyaUv8fakU4%U7}#&icm`AsmemZ9{+A&7 zkz!_LQ&tkm3M(jdgNKhC_4ISF<@oy1TnWjWPfRc1*yLUkNtm8a)3e}7hKeFEExalOw zGMr0rW>I@H*Q zSdvZF)>s~8leM*$9k{Nu`~`@z6%P`ST@^(wbZV~gvg!T?E@s!LQ@cT6OEET`HW9IT zqBcphW?h#xGix$3nKn^FDuXZ%%ylg@SVqRJxJ4(L!mL@hWGu>9m{BnqtYi*`<&+5^ zLNuSOWn_RLWnqQ}g0%619=8>fUC6gf1{{HA)U=ApL^y65tC&0+1R3)UH7vabzBC!4 zah|A@NXJW_Tn6HqbrZ_Myd(i795?g(iIc%;F*r<$bC6O^zFG(=8D<+9!hli*nLEWO z&~`1uLbLQl3mIvaUPC0-e$&{5d?*A{uS*@;&}f3R5sWR^r1UdRRn|+J2AS+i|MaW0 zFI>Zon!*i{U{W$kW)WL@jcUm+Ttk(+bG}oGobg54kU7LJE5*<@maBhQ3g>{EDn1pH zCC-rn`%FrsA`_8qR}LeyCq1%N0|CPDH@9lclG9NNdu0R3CTep~<|-0y@il=g#h4pB z(RTk6SSwqEt4%wfHJ)iWh!Fpaie@)&YOe7$HP3Epe9#wcs#b6TI#qMX8w?e#Axb!) zMNI~+-ApUKaT<;p)2CZ7RBP`e-^!x64pl=_W3xXzdxJmJ%ut_#zWR-HtEz7afCe`Y z%&zwbTKdWT0bgh~PJ%{yC2pW8glHGq)Z}X}sv}98Lp7Kw7UB#5fu1Z8E&Ui&jVy$n z=Emy#yfrmJNr*dN2x)`_KNUs~_ipeP1{y=YqH3~1sGcgp?3zu-X=OA<4bm88{UJfm zLY$07j6q}u-IXp9lIg31A%DN+)w03*&xp#?rjhM$oMzErc{Gb!Ls);oGX)xku(F1s z>Yd%#6qX_(t?bflALzHe zT0&X#HJDu)T`i=nv*Xy|8g#bmN&~DPYG|6>9IT#Qiw3AJoLe++o-tY7+`_Pub(XAg zB5Og>oVdGs{LPJqn}9di#5^8y@Og7RA=c~-{57Bt)dhXt8c)zy>u(PEf|T#s=xy-VZ(_^qH!hg(xw|n~!vb|R zJZpic30zT(Bxqsvje%NcO=HW3dS8Dnfo6f{nN&Yd@Jmae**pt~;d`+PoPCn^Rq&`5q<=naK}{tYc5A5fHECnrru*B4ed2GE>=P&2T>#+Cr$ zO)aVp)e#jyp)VK=G~xyogRuI(!locXNOh<&2qa=iVMAk$uYL)2BEPr3&=>Yqvu3Zf zE0m1ep}Nj1O#YBB*vJANQo8w}ep|xKz}EPhs|hO%BU)cH5l@p1iG7VX)aV<6Og$Onadfd`t5@z3L-p6fwR^=w3$E8QO}E0$fPS9*iB za7`$WHi@fB)?vtb07!$Se1Vz~%}a6Bc-$#(G`2=14@i`a{a#zM$4ERlt;%R@txE2U zbF5cMBgeI)=D1FAY>#uiPbG~U*A3!GBVna1v{u3ttZU}ov`5`mNwmfqWhxG=@v@4@ z!iopgA;}Y;AE=4KvvS{0%?;X<>^moxSA*RVSzZlum$Gkd#gxFMR@QO#XiT=S_=CoWk9oSyML!F`USF^~Fcv>e8KCBFjtRW67yLJdH+4;I8 zc-o~Oe2D4$P!0t>ddpF1T%6ABDPKLzejQN6|E2J%U!*Atx2M3$G}hkwKI4wl(Ekk3Cz{(I%74{rJKZ@3O+&mQ1O&YeJ*@0+=!avCQ4USj4CB8dN z@Tc;0yejbsp#$PfOz}yecVIn^Jr!1!fOkuLPQo~~M&ct0^qV+-u>XHk(mNCAY1g0X zbtcG3d*_5_3G}oBNcg=8czUp+vB7b2Ch$b>PM|O6_`!1i8OINf=d`)6(G#_V=g9Qz z20MO(#+O~dPeQ$ko3pg(JgF*^t(X3@kBZ}<4gN`0JUQUfodo|XI*4b0vN$~V+g81y0{r!+Ev{K^3F2P^v`(=r*&yey}R5$KN-IKjKf9w7=@C zUx%HYMg}r{is&s(d}On*6_WmFo~ZX(Y0tG1-*k(> z=g1drs(~kY68*MO($8oR^gE>dA&!?q7{J#hed`=Se}VQ8aqI-1r z{j*AC81_vKtNDRzaV)o+LoFLOVp;C-EL(f$U7pnyYu0)^xGOW<)%euzlPA>Rsm9ig zuNfpYjh@>2#tq(jPYpI!u=&vvX4Q=iP4&KzuLhfCgvB0K81H~=3}WBJQ`6GWuu0Xl z{EjkS(QS8?+`inS?)rJsW{u!kLfZg^Yg!r#=av=m9a_j+Hy114=D-SHz!&tQK0;Ju zQwNB(er!zPw!X1;uAuXW?vmSQw|krKYbIpS*X$dN^)@$nnmF@j?*l$h|81==giQ=l z)W5O5rMZrnG+;BTvD&yFQOu7y3yYfSL!N467c~X3#k0}vUa`8ObeU&v(VUyvU?Q+@ z^49ujoj(GlFYFJEK++&LyG9_B`w4t|1)BH+1L!?yTYum_Pvz>hFjZsy1HK`|ZfXh9 z23bPEgdK^&+M-zVfHH$gHa-~iheoo6F#iagny?qxm>^==m+vUKy<*uA8hJyF{s9aJ zY_N!}D31r5!k*>j9^ty>Wp}ZnwRbKnlI-Sg=x=;jv7s>_wy?Oj$G33!ZWUZ;W6v-4m6%HTvs7E0nZ>q=3l3@W0l$K|;jIY#$4 zlt+lcj;Y)Lqdwa8Zo|EH0Gwv^*{tcb^cR7gVruNRx?*g39k1P4(PmIqm5Lj#_o z0q5J$Qj6_kZvZh=-STHIDr>`rAY57A(enhAh7nYfLb;@noYYwQ86fS5(AkRMI~;#WCMiQj(_DNG&W<<rP0_FIJ7^oLd9@!7$d7_JrASD##If|26qQ%@Q~R=j z{GeCDjEB-+;dUWmEU)%&0r_!85lWa?|M!45mRI|{fc*F{q5j13&&l$NOzj6dKN02C zI#As8x1YMF^%~W$%By|j;!&3WN0gyOC# zBeHy@B9t(({Bhu^{^A5WRen+eUaBv-Gxlp)K7owwl@v}@KoTVCL;jgS!YRA?8$|T_ z?m*6ow0%j+pQH^`96wSWi{A~dD-~pkJc)EyhQQYLH!SCnNK0>96E4wy7qSGUietPm zE~>nOw4bZeiiY5fY=K>#keP7H@_dR5kVB;2z92W@cYw*UYD diff --git a/CodeExamples/Array-Sum-2D.power.c b/CodeExamples/Array-Sum-2D.power.c deleted file mode 100644 index 70c270e..0000000 --- a/CodeExamples/Array-Sum-2D.power.c +++ /dev/null @@ -1,1110 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBGE_1(h2_sValue_t P0); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BGE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int(*pifpii)(int *, int, int); - -// Sum a 2D array with a constant -// Code specialisation on stride and constant value -pifpii genAddArray2D(pifpii ptr, int stride, int constant) /* C compilette prototype */ -{ - /* Code Generation of 22 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t nLine = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t nColumn = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1F83F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - sum = power_genMV_2(sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = power_genMV_2(line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = power_genCMP_2(line, nLine); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = power_genMV_2(column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = power_genCMP_2(column, nColumn); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0003 = power_genMUL_3(tmp0003, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((stride))}); - tmp0004 = power_genADD_3(tmp0004, tmp0003, column); - if (!tmp0004.dontFree) h2_freeReg(tmp0003.regNro); - tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = power_genADD_3(tmp0006, a, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = power_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = power_genADD_3(tmp0008, sum, tmp0007); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = power_genADD_3(sum, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((constant))}); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = power_genADD_3(column, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = power_genADD_3(line, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, sum); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -int sumArray(int nLine, int nColumn, int a[nLine][nColumn], int constant) -{ - int sum = 0; - for (int line = 0; line < nLine; line = line + 1) - for (int column = 0; column < nColumn; column = column + 1) - sum = sum + a[line][column] + constant; - return sum; -} - -int main(int argc, char * argv[]) -{ - pifpii ptr; - int in0, resultH, resultS; - int constant, nLine, nColumn; - - if (argc < 3) - { - printf ("./%s \n", argv[0]); - exit(-1); - } - nLine = atoi(argv[1]); - nColumn = atoi(argv[2]); - constant = atoi(argv[3]); - - printf ("Array %dx%d. Constant Value %d\n", nLine, nColumn, constant); - int a32[nLine][nColumn]; // Create & fill the array - for (int line = 0; line < nLine; line++) - { - printf ("%d: ", line); - for (int column = 0; column < nColumn; column++) - { - a32[line][column] = line+column; - printf ("%d ", a32[line][column]); - } - printf ("\n"); - } - ptr = (pifpii) genAddArray2D (h2_malloc (1024), nColumn, constant);// Generate instructions - resultH = ptr((int *)a32, nLine, nColumn); // Call generated code - - resultS = sumArray(nLine, nColumn, a32, constant); - printf ("%d %d\n", resultH, resultS); - if (resultS == resultH) - return 0; - else - return -1; - -} diff --git a/CodeExamples/Array-Sum-2D.riscv b/CodeExamples/Array-Sum-2D.riscv deleted file mode 100755 index 80c5e7ead5d7ee0b2785ff843fead7681112aec0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41540 zcmeHweOy#k{{Nl11A`AChGlKFP7GWpzBnqjeXHFRaTMJ(b=9qHzgr{1h_pO4Gnl!i z=nPM0N@9q{8WAFq8mW=FW~h_+l#)wkW=d&dWnp$@d;)&&&$;)`3_bvB^m_gN=<1n! zKIeWu=i&W%pL5SS_cAkg&_WCJr~0H zGnvvzN5w_KfPx0;6nF$XWIOVu5CWM3T|+WmPqStqA|I3FvvQquq=RBAZeu#f0@Z^H zlJd~ZMShD_Ec_j6r3h3nx~`@Zt_R^dg|m<;&~>Gbh0rfV-6-ggPC>ag;cI)mE0yD1 zsVWvkT%({||1+*byyl?%Q9L&h*L~}E1!)w>9>sD4lM<&6Oo|_nl$eq}bAUC`7B^!^ z}o4Mq8?Ju&hgYk$%j$zu;5y1LZ*nVSEchHv}rTCjuQk5J)Egp*sQ{lm}r) zxR9N4Xb~Zqu9FSPoF;m(Ix6R#49bAhIFxIYSI|F;X7Btur~f^_d%?ElhrB(T{^uXJ z4V_ak`wwd$y5){J-LqTIIQv-tuynR@+#^jJ@_zpx%E9-b`f}hE9k(J(Mi}HH)0HS6 z`L~d3HD3KkA)ob;?}QxWqyImUbv|+~WH^{U;g=slN zZVp|<5t^ss{ABVNC{E+>{XB`sb0L3Mkxd$mugv9X&iZfDiTolErGB`{W zmx(x<;xc*1Qk)3wb1ci}xFP(G;rzNC?*{WDn)B!5JW0@Jm$8BhPebM^1^8UBm%7ItO<0{);U-VX6dH*^^e#lUf-Pgi# z!G2+XoIi2`7yOK>b>1jdO!u7S!_;}pUgEg?dH438pMi7swt2w_aRF{FA1KbN3C`R$ zZ+`at47!q!_`hDv|1>PBdEVBSGc%We*j8tF?+}-xW?q*6&fJD4hh@g-oj+!+j|wpj zSIy7Z_U?1fgdF1T&>Ksy=mky7;9^IAS4*Z=FNiIOHD_k)jp7xGeeI?zLo*{MkBpt4 zq3Z3wKV%;lq!&tC^r0J}>ug!Rmo$Pu?Hff>bKk9*4`+TkjM6e+m{*gptykY!oUfgt z*_!!9LU3mG{^7qZA+*eFC+FI2kRF~$ya@$%? z)M>BWH}ad`vz$W37QbR1^_Fr{tbfE+YKtD%DR$yG**rPK5oT)P!!#{lKXTv5*x#$T z^%FuEE%$%^S7BQp4$i@F$CjpQv{;)#TyKtujBa=98kaLFM?m6c!9m&|g$GPt4nW8aweQuSrFe)=9u8%u_U)_yEte@MTuNi~! zAkRPUPKukPc(B{w@!=SbFU#c|WxF|k^%&LB(L=OuHEMibU##WyB?zSmWeDX66$opz z99{PtnFD@6Z~nVX&Z{A*j(s*iwv>AK`NMlxz2+(HE_Y8>ufFb{M@N6z00v&bIC4R6 zKnO>OKrkZcG?y^)go+oazIuQ00we=ToLV0)UTA(?A0b|F7+mLhLpP2O8^bxmayeeu z%{hc_D!%_1m7{;I3c3EI4=+6j&!5v9UFY<=I#C~TQbfKYZ*X1!rWYJxnv1+(y66y` z7y16Ki;n)9OR)P9c4uLC7ItT0cMf*vV0SK9tNAfstNH2StgV@&G8==6rzVzpS{LLF zWUafKTKCP~!=sOmZti<=@s|xpM-R>X?0yJD05uHkk?Ei~1dmX1C=x@as~*@#yDfL8v1R{nrio<%FqqLpX!{WXnf=}&0s zk5WsYk9f4y)6RR`-B~;Dba#jMnvhcyyw?QpHNksL@ZJUV%L@*0OdlXN6`A0(rlThK ztZD7g3c5!$@dj5DAEt3*WOVa_)9nykZoWTk`kROiH>??dZ7Xhwl)yFvc zcjI3Aj_==1)%cg z!1vFkK6QsXfO6c{K=!*&6h*z?STs6#S&Zsk?OE0Hi{FLzlZ$apm0#fI-p%gConH(Y zrRNts%Vj3yXKOE}m|!4$n8lud zyl^l2^LdAETM&;i(Gfa4h`&!2)bhliF<*G{nXH{9uCncWs>dD62tYr)w9XlsTa{ZB zHSfE^(cr>uZtlZD71>3*2rFNPe1lYCh!6Jz4x1Pcb~OYPn!o~#u|-k4Pmtw1jXY38 z+HWwbqEC9cAbH)(g3N>`7Z;7bh6m`y*YM!71Dxl}OEh?zXP{u-0Dl|<4?#VlyV>M>0h-HW0= zBu{f6HSq8~c-hC@^#xIhIp?mnW%j{5L#VysGma_wr<53H6W8 zvCGSo11o=Np8VyRteTP!%XaM9Htu*vH;i3PKJ&X^&;0JUKJ&XfeCBtzUT=PP5B%tI zcffA9JiBwtvpYAN-MQK9&MnXG+=usCO4(c>$lcR30{w=~3$8n>!@S^nn zyx>CP*@0DHv{Af(nE_^Inv0kjU}omT%*=(E8Lax7Xl8aEa~2VE77=q65p$L%eaOis z%vqYQGc&m1>`$KCoR??7)39 zvjgpk#`+ILpPp5J{HM;d-ZK){&t-R!Yx+w2vxEA6XFBf1o}N`d?3+$;R2qTZJ|nPO z9)Xc2kHBtu1a@zYGMZMJ0>@l>BJlQaTKRm3z$8+EPSu+C~ zW&i)38Qh?DKXYbK^L1nWu)V&#H1Fw{D?WVO*?AUwM*RAIJ34=#@bdD54}R$p|A}X^ z4wclE9o$p9e}4w;wOx>At2{;`X}*bZiej{;SH>W=ruVE?{2e2)ZV+f@k97m?*)$s+ zx(qeH*ukiOQ6BX#%A@{8HtJtwqy9yC)W3Lm??YJi%BA&nYvh{U>ef&>FE?Vf-V>`T zT2KF1YZ%KKPkSg=sg;x~TEKE$DCbIR;BvHZ6d{!=$#be5@=O|t7e!$Xjhd~c`51ZOHt$>?>220}o$SXKJ2S(7rouDQ z-07*8ORiTC&G6T@jrFaIeEV>}MgL779=3o` zz2=?*eqXyz_4eW8S!n0AR@c1~dHe8ON2hv%bZ@!nb8opQ-&>F--&-!q_m+!Q6NJeH zll`A)8e_q|<(X&vKMnar_|G3d9(RDdllm}bZO*D(j}LwKP(rciB(Qy_OV~%bgng7t z*hjg9eUvL~uH-LX!d%H9Ucy`{T)fm+KlgPoHA1|EU93x3^X)a?I>#{>|Ugoj( zaP-$)!Cc9Wxe|6|Hey%Cg&%sIIIqH7={)v<+|pbr%t&5pb0@5S zb%oS#+V-+x%c+-n+8gBVe%SO{Ox!-1v7Wt?qNtBg$UO;jST=rOb+SxF4E3%=uI^c+ zcg^ZqeVuhjrx<*XcW>)fs^_+txczcHeq+bUuC41@?>K;6 zDS3SAqT1$md2N4WPg7#PYpfsmk?+_reqZN%yZ1idSkv){;vE}$ec1KAeDj3x$txyz zf8x@ZN72hwy+ig(PqloRcW*+l_F4bJ9V+bHxmv93iPb~T_#X>7DjfOa;S5eMlwP4b zdfWao@YMD1N^fBYpv?{xdWr1y-3|V1rH?yMQPewZ2kJe#2VmTnR_)Jsb|!hHGk2g| zFY|C8lz(JHmr;$cf>BpGm_c2UcZII_+&3tVc7>28-#4zv_l+y(CQO}taB}n$_jYzgQone| z^_kLZ`&CToOY;Pbxm`DV!M^WJ?(BF+ST=jX2>YQt!uF=Q%R6lD^1d>s>U-lk)eUw| zZ@OlyygR2D>t$BoWZh`|yw1$(rt2ngz2J>oT(2GWBl!A@ z?tpeYCN?g;KGRe4uVVV`o;%?-dG`~mam*~flgFdm=`KD-^|5E)llCwl$G&I%T<;F1 zG~Wo4p3>ln$h&UoiOsbhC3arZ5B`hMEBmL$+F?h1J!<~^zwzkYPjAMf{px<%(JNS` znull7bMQ=hPOwHb7xK~OXSek&S*9;rJxz|4zN^GaYNlbfdj+%IE12zG!ECn$yMyel z1bVk5pPu*h6t7?{iD<7&qy?jyKp_9_-n0i|;%cmRImJnchmFnJ@HV9VpUMWSwjs zB3@Zb&y*=gL8LO-b7ojxf@PZ-IJ4%Mb%=P0l^rTxdYkMhN6f@gTlS0-me)MNX4Y!< z%$hyHM$HBB0&0#Y*s#X)Ym|vSON8q@J!RG!v5D2PiIr^-n_eb6O2ac$ScGXl?$$zw+GES}ZtL@EtWnh}f$ zI@pCEgdzwUXu__i_yeoo56n)->_S8;=L~Glz~%?o`~aIDVDkg&0ZrHiif35OB)bst z2b32oQaRtk<_v7kz~&5W&cNmj>T!nIam+46goJvAif3Rah*ZwEu=y4?-@@iw*nA6{ zZ&8nLnVnkv7UhMCkeFY;g`Ghpo71p44V%-jISrfBusMx-oMv_!@igoN5fbbS;%V50 zi)3>OHm6{73O1);a|$-6P!Gw@UpxgngLsPBg^QPqO%~!BF37eCs2Q-=gzJgtZ_!YA=ieJG_2fJ`h zJ#6Y>QxBW3VDlAhzCt~q$^2IjJEK_7>~zd7M5MBg!R{FBj=`=TcJ;8Uhh07DQvdw3 z!~2FT>FTNavUjKI%WJ0U zD?Xj7U(+zPL(5oL#=>$6ET_P73M{9U9g7s6deu~xpscn5XWM!k?Xvq|`BwLP8rE!%khh zd$E3%IDQy-9R^;9f!AT+br^UZh7S%iv^3&jpe2Zq*jRA*BkHMSa|kwvU~>pIhhTFE zHizH?(hn66F>8PE5F`Uhunrdw0qY2oGHAR#)U{Zf4)X@*VLr@t7<){g@q+0yhv58- z@9+AoGgvzhf!Bw?>rcV!PkF)lsY7sm3SJ-X8my1+23~c*s}6Y80k1mXRR_Ed!3Ppr z0b(7{3K#1bS`lL1$23Zj%|X~4gv~+N9E43BZ0g_x(l>|)8P?s!gODOf0@g0gTU(`@Hz+|NNDvGYk`(gtYv8F#DkyEY>hD951ak4sfA4~ zY-(Xs3m=evgt(t!9VqUHq?4^f#9B61OL+;9XoSOP*EM5^>0{pD{209c7`#5n3#Nk( z!Fdq8KG+$ood>i~FN3trdqg0t2kxN5=ckGlqIa}n^`2fX$Jul>MlKk(WQy!OKf z5?UNXD}=BEGegDwpV5dy81IA4KG^Jo%|6)dgUvqpU>`$wAH!NLk`yXJg0&#-W8?L{ zAE~G8>sq8;AA!~T!Rq~B^?qJ(?RN;817P)m&LFMX2UhO`tM`G``*=a~kwY+j1Xh34 zHAsJu3AFYAtvx_%5762JwDth4J@CLDhLuL#1FQrQ60kCed%hr)$OdmABN!0E5h4(b z2s#bvhl;zHwZFIvl7S>xhl{(|Xua!8>LoZj0R zq@BCK>0RLTZg6@xFF1EQ1lMkGdQaCN-K!C3?F3pof!0o-wG(LV1X{b`0ST)BaVM|} z7k4tOBE+2xC9-kB#swP}Y+SI}37ehp0O=b<7el(c=zi6W;<-Q!)7~dw!;IYA0bvV zqyxojNIKa%MBL6s>h0U8mu&A^q)j_`gL4Nsy#t(f@q)?a5S%V>+SM7Po!fYWYa2Md z9h~0I3(oBh!L=Qn-qAHkAJ_)8wgRncpj8dDs)1HD(5i+9B&;}wRR|#mR)&hz-w;ZK z@K)Gth0RvjY=zBM*ldLdwlZwDGNjcaNueSnSPSA-HcoHFPDD83U3y1!eE?2ZgVWXE zbTu!ysvUx68#ukKGe~Q;g40{U>8;@OR$kD2;1En7fYTpz4blVO1X^2w))t_(1!!#n zT3dkD7I2^nBI2?&iBFT_dA2Mb2B)-8Jzw%IQ?&4 zaQ@pNxc&`JZ|NGO7cT``n}F6PptT8TZ30@GfYxSsfG`roO$@OBaTBC)l7Lu*xG9)- zol{m>u5)11PhiteVAD@v(@zfUSb@gKHD4--GpguznBL@4`U9Dzvc*ZLC5YH=&K2z!++oL9Al! z>@HS8iXaK?G>TQhys1fPrwM<_;KW}txSHTgH+<=aFWvAZ-mdJpotk%fgXvv9%=s>Q z&AU8scL=6U=rx;ezMYHTYpm|~Dr;vbwbQ&3ZQO`9ZbTb5qK#E(V-?z11wT{E!o`iO zojt{kkc=duojS1!Js?D^LR;!7H~RY~^p+~$zR)QY+VPj%zrj zjn#8A;feL|#CmvQBkVT96C2@)jbJ0;A0e)1-Ut-eL(<9K2oX01^G;D|vlD;6_=2`zw z7cs_M;=@dMdj@aO2zZM|(BSPE6P|f>%sSWGuwD=A^{`$K>-DhS0P781!n$g6OD9+t zinpPKQc-Wf+tA@IJO`-5bAXe04nV9sK>MwgK)({`R|5S?pkE2}E5X1@#x2PMYLTQ+ z@&`O1h?O$FtF!TZMx-3pA%}IyVI6WzE%kB1r;C$i*P8gCE1i zb+{*dr})eD9WXls%+3I_Gr;T&F#8^uecu_@wmZ^x=xt3UZ!lHzVa`g7w3WP|dD|hF z-o{A#c4xe8TE`ol>oCTwbA)N$;sw)N4#D{r-{19CXT0s%C&ZqiXaA7)YL$IkcAsK9 zwbci{3g$K6Du`*mMXkR@t-nRBzeTOTL#^>l)A?Oz5Nj9j4iRg2jA>_7#y$Azb}D<) zzW3wW10OqLoZl&b1N#!a9dTx8CPogLv8@5y=>EJ0Y+D1itpVHCfX~FSP;m`ooWHmR zl7S>JE?ivm5{)WkSpmxmSXRKY0+to9Tmv4Hz93dG>j1F=QaDMlju0!rSEE>gd;4hx zebZ@p{WQFO8eabfUjGJO{{~+FrZecb>${H8U&9+*YxpqDT1S{^EiX9NIt15RzCZe1 zXGW(A^t3n8)82H1Ip0K2d(#0t(bLv+IbYv(#JIlk^`hoG^5WuR+^jIJRZNw5rb!S z^51e3k4@hY0;zdmVL4b>4i=V!h2>yjg+2r!R72b|h~09$L;+^zm zitB4IrSkaqU`ZKRQU;ckfhFZ&NjX?jt`{`Kjc~DyF{P(i2FXYgn4$wy*xMD3)iKjB zDnjz^kSlopJVe^{MmvZ|^Lo>2^xM^Zm}@oqZ8={ z%mvL)dP6DRKfreYM7Z#_1OAp@hdEM+C^}+HqOUhJC&?SFb&Zw%_QD&b@J1=TQ3h|6 z!5d}pMj84v`5;0pWgZC>OCjlGkAyJ)2x8gwJkjp`v_o#TYu%wIoU1VYuHwTqWf*_U zc)?lb5L{&#e^+;nC;ENT2~V^)Tdi!}z}5~rtXM0DZ2;;eK)nR0mjLw=pk9JLQUb4( zFx=H*32+Y;A)zM-B54;xyBONV&@P5{F|>=}!(wQLh{eoKBa$SL1UrLR%x0;@7+<`r zjR=vfN>GPVBLK z*ByfCb(HaXXT~s7F?vlgdQCBU&1<}1dd(p?Uqi2X4c6`Oq@BHw+E;Ti%KVEVY{crU zvfsbZs+DNfO01$E3e1zpEo~m*SceV zuLQqWg5R%#->>q5^HuQsRq(sGi}<~|6Z~#(51_I&lc8^5{LTdGD}ee6puPgAuK?;r z;93#9Qp9lYF0KIX5#kDlyHOOQTT~DzPl943%ODC=X zzeB_o;GXXu4p|kU4n@ed2)WYJ#vWgoCaa}-tFQUHqn_?&a7Ovwxx|_X&w$mT0&8?^}y|+~W*R| z9`)zLOa+cGX8|v`3LJuF8Q8c*f$@U46z}91M6y`|nf|W~oLG!XhFue>`zWmE#ZCZl)0k1sZMeCnD;FSlw@_<(!d?2CaFXjO)gP6zA3K#S6j5b0fn?z8=J`I19$y#!t_ z`DL+oE#eKD#o+Z~@Om*XxE4Er3wWK^HCPY(0(dP1UJHTOLg2L!cr5~6i{JwZt?uGN zpcNr5WM~=1g?J}NClbaBV6y-=)HfEwW+7}A!Uv=uE-sMoCkr4MNdne7aUr{(NO^@q zy3UG2^CE9By$D{v2wuO)!>10xvvDlrIXPL5f|W{oKTT4&Vo%2Y;s_e1DhP!X;(H_ zodZ_qfYmv?;L33bnq06tw`-6-{ua>60$N!>D+_340j(^cl?4w-SgFMQpftP}q zg?DlcBH1`$&1y5S?tac793y#CbiWHCfUlwVT6P$K}(@tllf=FN?G*gEwgAfz$KA>3O{1n&$v2 z;Pm{iLHgDC%`@_|{paFuVep-b`Prj9u`Ew)ryK*08Ne|EzF{Z^Lpx-do^x}VF~Qkc zh~K?~@C?r0$>LuVni=t~;pcrd-W?^GmQ zDO2LX(g%W2atWhL*bDa_&9HTF$(%O2{7s2e=yrE_`AEtfY5f<}2FJwRO5Ne+1 z`-4;M>__~(HGyyWHM78^fAV25|8#_9|C1ML{^=03v-$opz_tt42GxzbWDk~WX9DM$ zzeOO*J%G5S)9-`IoN=kT{I&+%c|&pEwNB+Ut#^M8qdD?F&`4TfuXT84o z%LTF*)@iNqfE^yN!vl7Bzzz@C(Gz6k8LzEAUdZtALWvS*j4xFrc%iJpj+qbJ$GT^+ zTvj<<_xeIgbr{;+O}wE$6ziLRAIaAzH8zY}c8ptgj9Ye$TXu|F=@_@tyTm8O!;VVz zN87P>xW6utqC;iuDj*ug!1pUMW@L%xh(e1h17hSm8Cc zyYBH?1zo?^YwbSc=+J97|2~he*R)oQl~#&z!dbqG^rdmC&+3@ktF!AT!}MJRVWg2NkT43$R!E6 zBq5h1J&o`%xX zP;SN5=tsl;;f`{kK~A9I=;TlPQj>{f>ALQqhcyX#Z-)nsTdX0;LCR3 zLG{h0CJFsG8T~jJ{Wux@I2rvo1^pN(-}vsy`0e}mn7;46RK9u^e*Ds>_f=@8qutZd z?&(1NX`uczaCsWIJne({!iMP{Kdw{a42R+dSr55PLoWDhTI5uMP>N87P_Fgbu4$0} z2A{EGks`4kE^Dz|OO!I$J#adW^KJZCrd&tvPs4Xlqx7dy`qL;q38g2YbYI3SP-=;i z)+ljS(mIdi(Efwk=<9))M9d!&F@H#OglV6~{NZWLAD+hi0p)bwkJ$-eLju?^9c-8m zHcST_&?ar-&HJ%m9lv_`0`g;HUhDbrtaVxZs(HDNRoilhXv?A=&KdHcziLBvRn&$o z?eMB>$L*YIz_lGH2fC;Kw$p@|XRU`*?A1-@kHLqqA>Qc!}O8XbCHSAluR3 z*@E|Y)eE#(**4Sn0h(GCXg4oozs%6G89VNp=FQ8ndT*gC_>~9zq6Rb}Ih#)mcjMdZ zoj$+);J|m;pBUlBH?w+w>BIMX&nABK*xtYGeyV2bhtqaEz3qo%+?{%%^nyNgs**eZOR8Om~A zcuh{}hi9@<%G+{EYY9rgdz>!3&#AfW2s2%#Z$Z~yY|Jy4I{Hg*cjjlgTlJxJm$qVe z32*7*8yFm6&L*t*o7QE0KR+__c0YYcDV`RYF6_omYTbo(Sq1*|-Dz91@|Ox+zCWx( zm^J(ESxwXCtOs74_b4Am`IwN$kgPJkB5Om|7wYu|;aNlcA!TmZyo!%paHybaLH=W# zRlx;+^?U~leeFw*CE6jXAEOpzzo^Z1 zEYMz6Ii zRxK;sk`@?nY5p>O1X3kGGhO)W@;48G zA$Y!Ly66aVUL?=gQ2U&Gf281PAHJ!bn-|j?&;0p&UFWHvY0i7U&+F+w9{J-R|Fro} z;bT{f?fz)flkEGwI5ihGIF1V&6dA93SU1s2WM$ub!uj$6}MlTd7t9b+Oh&`*fV29cxL!X@+#NS`x-tQ%R0Z zO1F$jPDY(a#&C}fAInV$i+>oc85kBfFf3mB-?sco9Tv}d>KYw0vZK0sbSM2Ky7Rgd zJ5u%5VYtcEk+P=_k9VZWdGmeru@03z`F31gZ@$sPJIvQOFwCa=!?>}DDVCu)k4Q~Q zPfkH>L@Ia@n_}020O^*Y%x}Z3*4XECVevD=;*Gkt3P|k^&OS_(#aTyzk~q~}{O`{q z?H+_RFSoV^;J3IA;e0pFXK@~cbDx6NRuj&HaGs8HB+j#Oo{n=d&YN)Fg>%NT*4DE) z@5H$eey{5c&JW@|rLeVi3eM#?J8=$J-r8D@^Gcj+ao&RS1)NW>M0xmaui3Am9GpvE zNB%gsl(n`V#<}2)*47{m$Ng<>YwKv7quy?9&A|C-oJ(=e+WF7-JR5@zWQb!~Io@yNwN$)ViY3S{e z^agqLHZwiSP)FC`qa65ll&mM0ss4jpDCvYkrvf^Hq=WXbdi@#qQyG;k9|3mG* zAF5HXt9%7qB1c9CPWau;?6u&G?v+WNx{+Fy5__ET9p4aZHxm{JQKp*~lYwOPf$_9@E%waKti zWBmEsa0sTrv%OdaO~j%<4DYEv+sgzhnWX+lW7Z(CwY37O$luc+ie;`(Mly|ORnXZl z)xA>nH>JV(eoOsd))oXT>sHu(d5;x6U%7=ruteQc4Pa3>*)4U^pF|&u{xte<^k>mW zqCY1fe?5Lh;8z5GMc`KiensF{1b#)}R|I}G0*mnD)gr=S1ez|=Z)NKc==bICr85Hk z)_4HqyJVTxl06~QT9K|(*o5DbKi|@t%Bk@?){rB373Yuh-yzfD{uKoJ`RpKs+YsoW zY4+WD^b6e_=S1j(KtGw?m*V&>a*ESA0B5>RKaWj6m)+9ZntBrXx8h87K8y1%$TxFP zd&yFVK=n`#S3k zQWNB7oiQXbF*0qiIXNqNYWWe(gch_37YREDS*56O%i|5@Sj1m8!h(#2N`sy zn)0ZmrWleYNb?F#!M}%Ux8DXW#WmGrztu?cyPGw+$9Y@{@_%<0lKfvo-2Xkl7{odM z?@+Y==I(PLs5yQTPOJ>#9xLM(PDP1oO3)63CBGao6@92*r?eJITT5y5p?;Ur{3(q* zr=kz_UP=q0v`;9FKGetY(c>GW1!>*kREJMd8!diL2I-u?6Bo3XdcBX6+W$o)X)pJA z9fHQc47%Eu;Gy6M7L(uLl8Qdm1Cicm6F%aGghhO;K%OVaG2x-FD)4cJZBdP>*s;P{7dQAHo>d{QH)^8cbV`cSW?v@MkOHl@*r z`rni`jnc@mD*8|#pfnw7%6~>_^r1dMX*87a-%}cWsNIzIESk!z@S&m)bq|V>>(sYV zY$e6|QEWZM?xWaFiVdOI5sE!RF@jYcLotFw{b!1mQ0)IGRz)!j#r9Avm14&z_8i5| zQOrRx@}-)3jNcvj(EgS&xyK@uqS5vv2l>;YTzhY?Wr#zIPTJ>heFyQ|g0#o|M94ks z@bP7L7X33Uzv`g@(mkt?dZI@kM7eI%eJGKUt{2yh?CA=VwOqGtkjXtV@q2uQLW8tl z5D)x+#5L{7Zo82k@gE=K6iqF6`*tL2HPm0a-|26|gfN3Z%Zu`4`|bU}V5uIQ8`JiOT__dQ{>R#PPFm>h>=vRU;zT?T+Kf zDjyDej@cg^u1ht9wIL)wjq0LiXcNCgF!tq;W~ZMr2iQ zRZ!pFs#|;Ufp-Ol1>(UFr#5nY;IKQ#+(yYD%kL>GRWGi`y_zw>xct8yop^zrG@)FN z9z%QZ*z@qa9d-}*_lTdd#SmU*jFw^ z*15ws+ZPSWN-r8#pQl3awE^#t}|G!C>qXN$L_*#@#{%|JZVvD%H3xPhr@_JPl& zTT<+aDFf}vX#;K6xPb{tiBsbSL>hef8niFlQK0->YHH|Zy(=i`_rk%4TraWMtmX!KzV#+ihz4R1WY48K2 zG(FX7$73tRJh`ULlx%Hrsc9B-A_`1QF;9z4PE2}^OPL;Tm9D125IIpH>Dn{5bQ3i6cioI$^Roddy^R87Vd{DK#ZQ$3CcZuaur* zOH4?y#Is7FIS-hrt%DzsYyBW9-A-wf#>9*pK2|CWwI)+8B{tb26%e1AJ~he0*<$79 zATLjGanob14EPa)2g?&w-GJoSsfmvyCZ!F*6?w$Q{bN9yHPvp3v!`06#JJStWIUus zHqaYjv0777Axs!E5})=Y+kj*|kxqIfF(uKS7@IV}GSd>r+&Rl)P32O|1dVN$*DvrU zQsXVQI7*e^lXxV#pT!xdz%V}69xD^bgJK&d#V2v*=+x9CPWA-xO<|cOHN`8$5|ixH zt(Mq$v(1t;4Rx?Tmu6|t(T|RanK*p%$hNea8TmWbIuAFco`B*hg^E`^FZZW$L}w4l zhD35!o8=jEoDKaZHo<0|nn)FsDfl3wpo7^So8YZ^qPG>^#8|2afykN1j7R^4AI<4D zyhA|!`u|&cwa29EvhN1;`Y*@2tH(@E88dySG<#Cp5n4)TpF<)Cu)GGK*A7ffiAze4w@A5j zL{Xb@Iw}kY+tH!zDPD<&VG>b8N|b3YM=f?l66rE9#3!+ir6k(XS^!{Aj2mFJB&Ehd zyxw7F_h#J1*vgvY*c=Utyu50s{RcXD{9_099q7P{i=Am7LXt5T!$JEKbntAK0?)oZ zGVMBW9PKaA!L!{5n%OFHHlAu{T4cSwqt^cnn&)<(v`gip1YOF9QIM@;5p2iaL~RA9X#7r!Sg+j zEbYEb@yNF`z3CpAc3->)&(Rdid+=;G$X8b0ERfQ8woBxDoxM@uN#NO=8Xgh#V^6s~ z2|U+N_OO(s;eKrGi75G7hcoRKNj3IfryOWXCLKMvDTvU%mLgA=V|1eYQm>NdTqWm1 zULo77v1>*7D>Ch3y#RTm&-Im%Y5$B4(%*}FNttoTpG_2y_{OM7l~kp53N zEB>apHf~j_j&!PTf5>^rkC;sPJqWoFGEE3crWJS-@_PWXQeTp#qX#!0QIl51jgqg& zLtX$`kmXsBi+%EULN4`@^CAD$Bj3iYg8X+M`8~+QKk~E+{G(l$eE}-2K+d0*x>LKU z7>-oGtMRVI^~!Y0gzTmMzyy3y`;Xz0(%)z|@d9Lp|0?ibh5576zpzZ?=-r(Os1F?~ z@Sm2|p{NhdcyC4dzk^&Y_h0HgBO%xN$bW@g?;}4&LyDZA4(&_F^$fI!-n*du=$)W7 zm}1lW6eKUfISQ*pdQXDn*KjVE?StU2wUE#H(i)wDdRL3xCQoIu)0csN(4PJYDYwIl^DXO^{_;IM0T>OO|!iKAA6s2ff4e z+j~?Ty$3<|v^Swa{=N_Zp9jo z-qj#`&S&D_Gh<^bu~aT}=Fi3V+_>W{cw3XbPHMI% zo8z#=vDh$&j88QuB&AM`O)|%07LQ4G`b-XUue2nK-4c&o@#|`sr=d7=EWHwF#wybK z95>C1xw|<&JvsR~nD|Iok|o;PsIoT+2TV#&9uR3VvRMskH$4)Hwv-s@WmQa0kwCAn zB4KhO7EBP6QWGL2y+ph6X6&P}wtv_t(Q2_-u1$@#C7aV&=C;@w7PD7m#XiOsE_job zWk4JMQp)3r@%HK5qzSAr_L?ollG#hRXxylY!yg@K9y!irHgi}{jvq17^p}Yv&11)m z`_u54k><(6qsNZK71I;rhCe!H1Pn0GHjf-F+l@9&NC4s}`c!96f20+?+Hk=84n1IpL~>t*gxDNv7eGhnu5E#*7(9?KZa&8Jtw! zMBn@$easxm+0v7l!#S4sM9T~%k}wGqOA9s4=3AgAtH*t_nh2N%ah92hc3)j^6N^51 zO9JpESnQapDuhUwWU-F{`B2$-TdH|_Y)U*<+majGngjcHk;f! zpT-&4N@#fWm;to>G-5GgoE~eN&KcvMOM$U;wp*nuGb~mc-dt}Zm~jm& zidbV>5|%)A%S?P)QyJBamg(~NL91bp#2M497VlWX8GYm4;fNKD-2tr9q}&oxk+n^V z+khu$WFNG=#K?tGsoxu8?RIP8)O0(BL}R>VYI*`jtk@K|L=oApm2zq7R4aHaOSEsI z!~v5MrDXWd%5FrR{J0BxbmzjYh@&-?9YTnYEnTBSk3cIS(xbUI-5zy_D+g{#?D!o% zX+=ePvCrP{GWa{9SL@NXIIW;akJfB|N2C^Ue*{>u z{AeCA0s*&YrblbJ2ner0Ru0mo<4*|moS5>XHQp}h(TYVWm(nTx6@i{BQ=Ha*C!se8 zao=(watR33rf39O6Vek8C*qV}9|XEa>y;z~ssq{6+_e}Ns2$2dZJ_WBf}%%r8hX#$ zPKC$^PVB;BM^uz>R`lp`nxaQ*(M@T1M_0M% zqqhukswZJhYg7#i@KIxVkX(j9Gk4OXwM@WOdZa^PJp!$8Nsrb7X*{pvSg~9?hlh&fvHQ>4JPH^*abz(W5!) z;BD+6;>ipYmjE(=Lmz-Yg6* -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int(*pifpii)(int *, int, int); - -// Sum a 2D array with a constant -// Code specialisation on stride and constant value -pifpii genAddArray2D(pifpii ptr, int stride, int constant) /* C compilette prototype */ -{ - /* Code Generation of 20 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t nLine = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t nColumn = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1FFF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - sum = riscv_genMV_2(sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = riscv_genMV_2(line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = riscv_genBGE_3(line, nLine, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = riscv_genMV_2(column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = riscv_genBGE_3(column, nColumn, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0003 = riscv_genMUL_4(tmp0003, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((stride))}, immValueZero); - tmp0004 = riscv_genADD_3(tmp0004, tmp0003, column); - if (!tmp0004.dontFree) h2_freeReg(tmp0003.regNro); - tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = riscv_genADD_3(tmp0006, a, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = riscv_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = riscv_genADD_3(tmp0008, sum, tmp0007); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = riscv_genADD_3(sum, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((constant))}); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - column = riscv_genADD_3(column, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - line = riscv_genADD_3(line, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, sum); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000005]; - line = riscv_genBGE_3(line, nLine, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000001]; - column = riscv_genBGE_3(column, nColumn, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -int sumArray(int nLine, int nColumn, int a[nLine][nColumn], int constant) -{ - int sum = 0; - for (int line = 0; line < nLine; line = line + 1) - for (int column = 0; column < nColumn; column = column + 1) - sum = sum + a[line][column] + constant; - return sum; -} - -int main(int argc, char * argv[]) -{ - pifpii ptr; - int in0, resultH, resultS; - int constant, nLine, nColumn; - - if (argc < 3) - { - printf ("./%s \n", argv[0]); - exit(-1); - } - nLine = atoi(argv[1]); - nColumn = atoi(argv[2]); - constant = atoi(argv[3]); - - printf ("Array %dx%d. Constant Value %d\n", nLine, nColumn, constant); - int a32[nLine][nColumn]; // Create & fill the array - for (int line = 0; line < nLine; line++) - { - printf ("%d: ", line); - for (int column = 0; column < nColumn; column++) - { - a32[line][column] = line+column; - printf ("%d ", a32[line][column]); - } - printf ("\n"); - } - ptr = (pifpii) genAddArray2D (h2_malloc (1024), nColumn, constant);// Generate instructions - resultH = ptr((int *)a32, nLine, nColumn); // Call generated code - - resultS = sumArray(nLine, nColumn, a32, constant); - printf ("%d %d\n", resultH, resultS); - if (resultS == resultH) - return 0; - else - return -1; - -} diff --git a/CodeExamples/CelciusFarenheit.aarch64 b/CodeExamples/CelciusFarenheit.aarch64 deleted file mode 100755 index 3cc903f9dd5b16ccb2d95517dd25b29752bc1661..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48128 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 diff --git a/CodeExamples/CelciusFarenheit.aarch64.c b/CodeExamples/CelciusFarenheit.aarch64.c deleted file mode 100644 index f996194..0000000 --- a/CodeExamples/CelciusFarenheit.aarch64.c +++ /dev/null @@ -1,1306 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -// X * NPowerOf2 = X >> N (immediate shift left) -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSR_3(P0, P1, P2); - } -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (aarch64)\\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genC2F(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); - tmp0001 = aarch64_genDIV_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - r = aarch64_genADD_3(r, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); - if (!r.dontFree) h2_freeReg(tmp0001.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - -h2_insn_t * genF2C(h2_insn_t * ptr) -{ - /* Code Generation of 4 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genSUB_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = aarch64_genMUL_3(tmp0000, r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); - r = aarch64_genDIV_3(r, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); - if (!r.dontFree) h2_freeReg(tmp0000.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK; - pifi fC2F, fF2C; - - resultOK = 0; - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in0 - printf("// Compilette for conversion from celcius to farenheit\n"); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fC2F = (pifi) genC2F (ptr); // - res = fC2F(in0); // Call generated code - printf("%d (celcius) -> (farenheit)%d\n", in0, res); - if (res != (in0 * 9 / 5 + 32)) - resultOK += 1; - printf("// Compilette for conversion from farenheit to celcius\n"); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fF2C = (pifi) genF2C (ptr); // - res = fF2C(in0); // Call generated code - printf("%d (farenheit) -> (celcius)%d\n", in0, res); - if (res != ((in0 - 32) * 5 / 9)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/CelciusFarenheit.power b/CodeExamples/CelciusFarenheit.power deleted file mode 100755 index da8d19922cdd6e1a180e5a93d5767b5a7f8aadbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78272 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (power)\\n"); - #endif - P2 = power_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genC2F(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x780F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); - tmp0001 = power_genDIV_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - r = power_genADD_3(r, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); - if (!r.dontFree) h2_freeReg(tmp0001.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - -h2_insn_t * genF2C(h2_insn_t * ptr) -{ - /* Code Generation of 4 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x780F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genSUB_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = power_genMUL_3(tmp0000, r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}); - r = power_genDIV_3(r, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}); - if (!r.dontFree) h2_freeReg(tmp0000.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK; - pifi fC2F, fF2C; - - resultOK = 0; - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in0 - printf("// Compilette for conversion from celcius to farenheit\n"); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fC2F = (pifi) genC2F (ptr); // - res = fC2F(in0); // Call generated code - printf("%d (celcius) -> (farenheit)%d\n", in0, res); - if (res != (in0 * 9 / 5 + 32)) - resultOK += 1; - printf("// Compilette for conversion from farenheit to celcius\n"); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fF2C = (pifi) genF2C (ptr); // - res = fF2C(in0); // Call generated code - printf("%d (farenheit) -> (celcius)%d\n", in0, res); - if (res != ((in0 - 32) * 5 / 9)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/CelciusFarenheit.riscv b/CodeExamples/CelciusFarenheit.riscv deleted file mode 100755 index 27d38396a1c75b950c4aa342146d67a20fe1312b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41504 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

&&A|66SN&w$L5faSKQT#(dyacmz$FLI+i};al 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 diff --git a/CodeExamples/CelciusFarenheit.riscv.c b/CodeExamples/CelciusFarenheit.riscv.c deleted file mode 100644 index 2bf1682..0000000 --- a/CodeExamples/CelciusFarenheit.riscv.c +++ /dev/null @@ -1,902 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genC2F(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x73F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}, immValueZero); - tmp0001 = riscv_genDIV_4(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}, immValueZero); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - r = riscv_genADD_3(r, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); - if (!r.dontFree) h2_freeReg(tmp0001.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - -h2_insn_t * genF2C(h2_insn_t * ptr) -{ - /* Code Generation of 4 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x73F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genSUB_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(32)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = riscv_genMUL_4(tmp0000, r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(5)}, immValueZero); - r = riscv_genDIV_4(r, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(9)}, immValueZero); - if (!r.dontFree) h2_freeReg(tmp0000.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, res, resultOK; - pifi fC2F, fF2C; - - resultOK = 0; - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in0 - printf("// Compilette for conversion from celcius to farenheit\n"); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fC2F = (pifi) genC2F (ptr); // - res = fC2F(in0); // Call generated code - printf("%d (celcius) -> (farenheit)%d\n", in0, res); - if (res != (in0 * 9 / 5 + 32)) - resultOK += 1; - printf("// Compilette for conversion from farenheit to celcius\n"); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fF2C = (pifi) genF2C (ptr); // - res = fF2C(in0); // Call generated code - printf("%d (farenheit) -> (celcius)%d\n", in0, res); - if (res != ((in0 - 32) * 5 / 9)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Constants-Operations.aarch64 b/CodeExamples/Constants-Operations.aarch64 deleted file mode 100755 index afcc3ff66831d5d73e2e15206de644962ccecab3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52312 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -// X * NPowerOf2 = X >> N (immediate shift left) -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSR_3(P0, P1, P2); - } -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (aarch64)\\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} - -/* End Header autogenerated part */ -#include // -*- c -*- -#include - -typedef int (*pifi)(); - -pifi genConstAdd(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genADD_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstSub(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genSUB_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstMul(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genMUL_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstDiv(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0300, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genDIV_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -int main(int argc, char * argv[]) -{ - int in0, res; - int isOK = true; - pifi fPtr; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in0 - fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions - - printf("// Compilette for simple addition between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstAdd (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d + %d = %d\n", 42, in0, res); - isOK &= (res == (42+in0)); - - printf("// Compilette for simple substraction between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstSub (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d - %d = %d\n", 42, in0, res); - isOK &= (res == (42 - in0)); - - printf("// Compilette for simple multiplication between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstMul (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d * %d = %d\n", 42, in0, res); - isOK &= (res == (42 * in0)); - - printf("// Compilette for simple division between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstDiv (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d / %d = %d\n", 42, in0, res); - isOK &= (res == (42 / in0)); - - return isOK?0:1; -} diff --git a/CodeExamples/Constants-Operations.power b/CodeExamples/Constants-Operations.power deleted file mode 100755 index 24b1682f4dcd421f03e8efae3b955c4c93e19474..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78360 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 diff --git a/CodeExamples/Constants-Operations.power.c b/CodeExamples/Constants-Operations.power.c deleted file mode 100644 index 2520381..0000000 --- a/CodeExamples/Constants-Operations.power.c +++ /dev/null @@ -1,1067 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (power)\\n"); - #endif - P2 = power_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -#include // -*- c -*- -#include - -typedef int (*pifi)(); - -pifi genConstAdd(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genADD_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstSub(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genSUB_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstMul(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genMUL_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstDiv(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genDIV_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -int main(int argc, char * argv[]) -{ - int in0, res; - int isOK = true; - pifi fPtr; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in0 - fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions - - printf("// Compilette for simple addition between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstAdd (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d + %d = %d\n", 42, in0, res); - isOK &= (res == (42+in0)); - - printf("// Compilette for simple substraction between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstSub (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d - %d = %d\n", 42, in0, res); - isOK &= (res == (42 - in0)); - - printf("// Compilette for simple multiplication between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstMul (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d * %d = %d\n", 42, in0, res); - isOK &= (res == (42 * in0)); - - printf("// Compilette for simple division between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstDiv (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d / %d = %d\n", 42, in0, res); - isOK &= (res == (42 / in0)); - - return isOK?0:1; -} diff --git a/CodeExamples/Constants-Operations.riscv b/CodeExamples/Constants-Operations.riscv deleted file mode 100755 index 0f07a2cf7ee2eddc93ad8b5b12d29f01682cc510..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53860 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 diff --git a/CodeExamples/Constants-Operations.riscv.c b/CodeExamples/Constants-Operations.riscv.c deleted file mode 100644 index 8d7de02..0000000 --- a/CodeExamples/Constants-Operations.riscv.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} - -/* End Header autogenerated part */ -#include // -*- c -*- -#include - -typedef int (*pifi)(); - -pifi genConstAdd(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x33F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genADD_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstSub(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x33F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genSUB_3(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstMul(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x33F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genMUL_4(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -pifi genConstDiv(pifi ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x33F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genDIV_4(r, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(42)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (pifi) ptr; -} - -int main(int argc, char * argv[]) -{ - int in0, res; - int isOK = true; - pifi fPtr; - - if (argc < 2) - { - printf("Give 1 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in0 - fPtr = (pifi) h2_malloc (1024); // Allocate memory for 1024 instructions - - printf("// Compilette for simple addition between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstAdd (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d + %d = %d\n", 42, in0, res); - isOK &= (res == (42+in0)); - - printf("// Compilette for simple substraction between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstSub (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d - %d = %d\n", 42, in0, res); - isOK &= (res == (42 - in0)); - - printf("// Compilette for simple multiplication between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstMul (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d * %d = %d\n", 42, in0, res); - isOK &= (res == (42 * in0)); - - printf("// Compilette for simple division between constants\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = genConstDiv (fPtr, in0); // Generate instructions - res = fPtr(); // Call generated code - printf("%d / %d = %d\n", 42, in0, res); - isOK &= (res == (42 / in0)); - - return isOK?0:1; -} diff --git a/CodeExamples/If-in-Loop.aarch64 b/CodeExamples/If-in-Loop.aarch64 deleted file mode 100755 index 7d24abd538baab0e56deefcc7b83b7db5c559bfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52344 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 a12(Q7{fz-yqVi?0i1PIAhJM5)+5Z4W)Ije5 diff --git a/CodeExamples/If-in-Loop.aarch64.c b/CodeExamples/If-in-Loop.aarch64.c deleted file mode 100644 index 03a600b..0000000 --- a/CodeExamples/If-in-Loop.aarch64.c +++ /dev/null @@ -1,1471 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_NE_I_I_64_1(i0) do /* bne */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0x1 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_GE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_NE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -// X * NPowerOf2 = X >> N (immediate shift left) -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSR_3(P0, P1, P2); - } -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (aarch64)\\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -/* C compilette prototype */ -h2_insn_t * genIf(h2_insn_t * ptr) -{ - /* Code Generation of 22 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_endtrue_00000001 */ - #define h2_endtrue_00000001 1 - 0, /* h2_iffalse_00000002 */ - #define h2_iffalse_00000002 2 - 0, /* h2_ifend_00000003 */ - #define h2_ifend_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0F01, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, LoopValue); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0002 = aarch64_genDIV_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - reste = aarch64_genMUL_3(reste, tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - if (!reste.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, reste); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_endtrue_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_iffalse_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_ifend_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; - aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_endtrue_00000001]; - aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int selected, res; - int i, tmp; - pifi iPtr; - - if (argc < 2) - { - printf("Give 2 value (LoopValue)\n"); - exit(-1); - } - selected = atoi (argv[1]); // Get threshold value - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifi) genIf (ptr); // Generate instructions - res = iPtr(selected); // Call generated code - printf ("Result %d : %d\n", selected, res); - for (i = 0; i < selected; i = i + 1) - { - if (i % 2) tmp = tmp + i; - } - - return tmp == res; -} diff --git a/CodeExamples/If-in-Loop.power b/CodeExamples/If-in-Loop.power deleted file mode 100755 index 5f619834866535b5ae37302561bb6082b91ecbfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78384 zcmeHw4SZC`b?@9=eXNiW%ZIUS6LT@(N(2dk9kSS9BmqX^%ZdS;^toLv(n?xetQ2Ww zi$pSl&=xmN3k^%%LT~LhLRrl5>B+yLPISfVYE;jRuFtD%tE*jLJG{>IKXe`82`4XY>+j>8J-auko{N>sTLRZhb$C76aQfpFlavInqNi1@Y~wzEpNO ztK`>Ex5K=K$mWGN&TFVycwq&-R0=({v&QhyW&@W7ZuS|iT zkph1o@Fvd0gLX?M=kgTzt5e`7rN9@az>9EOBqo}|&CQL?qNz33!b^312sh1qG>&% zLFS?_S@!t99`}08GArMK*Zq)qzwk&_S0K&4qmMiXUJVtQWjgSBj4~tNfp_|`Vh5gm zP#*yYp5s6tB@Vn({&EMN<4Yfv4!mXY2Td6M>}X6Z4cmjSnjmdS&A}mJ&JZIfsG7d zE|PY|SVG-zL9VwT>%)$51ziT}(}l9V*6Z(o4YIUlFKutTCer>>BdfhwEM4@>Z31m? zE;7Z^J#d=kfZHh-?~%W~DYu{lP^M{*v(}E1>mXa(>X{vtVrc+;-*S%UPB?SjZrV?< zZuT>~?z`LDWl6jGKNB@5to){`%Glvb(wk7Um2Al|YH79Ghf=xAF# ztD|lGvW~~#Ye@4!X2C{N6u^!Jb8}Fx2>QU!mfs3U+7GPFi~a9b2OfLh_D!@;CuGv1! zgIrlkF3?L_=p@@^7j&S0wY4Qn>S|YozF1k&(KNNZqv?Y=9hD`kI>w1rAE_*#(?Oe1 z_r+pI$zb|bpfBjCtSpdpy54-$yXQUI9#c>cZBz_ghr*E$?G3nxX|_qs>MR*2sseqA zM$4<)ZVmXbokk+BQ;safPq#7P9;R96VO8fJD4M%PuqVp?w|+VL!OV_Fe`BqtOktJJ zw%t9#wq?KM__X_F9s1=iwCP{9x83j(+BFk?#R@#Ll>O7!K1)nr^vp`8$F=7>+Iy~Q zE7p4$zRyJ7+jod|dtBMLSqhhiaplC54{3b~__+$7_Y%XmaZk0AtU zw-=XZslHeNI0t=K%UiMMdbBP35qZ(~0PbNK=_^%wy2#4kYi%!KpAB&Q^!AVI-BRxo z=w9)#WpVt^>?j#Ue@N{k?Y5*Iu-*3Jb(FoJ!}dK(_fTH;*JL_NdZlx3xjha8<%4yn z9V%0_i?gpjQC2AJ@wkU?b3yA$VgVeo;zGTPwf~}_D+$E~^N}E^gnel789XP+B?mnD7Cq)J4j~?m^ z+4`J3GR1)a{Xo9h)}8JsOJ9b0x0LO>3GMsjyEb3TstWu@rCG1t)&&osZ$xg%D8MGR zU~T~An3vyqT@UUtPhAgN9l*TV86dwV@cWVC@jm!H?chh-k9JPbW5a}vaCZORulj8; zn!e|pEA>2c7(9={?p@;f-s9p-?@3|xo)Xjh&ccq}BG~sW*j3r8Anix`6!5yv6G&^m zT}Z#D>NtY*caffQs9+<<$6mvR!e0>PSpOOFuI;pOuX$|9zRA3C#?qerO*Zb9G-qBx zN19O(I+FQ2(pPlJ{#MYFCbFcD>)KuhI1c^oXKfhwdk&+Hqr&R$64QH*L*J9)OyKQ> zT<7%kLZ?2zsOZa6zBP~~$`kdbu3B%};KS5=`55VqnBgG3O^4pbDD-BV4r=dqyS>>L zE~dSU#n`lWdFJJ<_xv%^yE0>Fy)l+P)PBBmjQaVe^uc!;xL6YzRl@zU#2^2$=Y^cpG^uM3J-hGBJkjOjhOST9j7k3+6+ z|IF5rYak)yKB$k-hcyo&*FJ=KYMo@*G;+-pK{^flCYB{0WhCB2I!C1~OY#7ITlemZ zSTA3SwQcwpBU{@pQFP9=?NPKj*S1{iJf+sQT7?Mm^#f+gxjF`Hwi{Kje`A5hXwO2D^umpKG_|>$6L*$2p8u?VEKw&^P~gX@|MW z*W_c&KJ@QH`bX)0bL@imVsUYDzXC{;16v)KD~WAA$& zd*5E{eT8B5`i$v)eq(80o)PTJG3>o6$0zrV9INd}3&dR?#QvCYuY!*#co2JBmV@7V zcoNDWf6r9FeSi~xZu=C_?(rGh0;Zv3u`^`M4t4jS?jF?L^Pt$@y%#auN5q-#gTm^Z zf%q-Qk=~2Hm$1iv7V{GK;=SNaSvB3&;N{%2e_qk$8Md6Ny=l_2Z&3>c{n1muS7aF$Ot)IiH_)jNg;M>+yRGX+3^9|7$<>6w*n@Z|}(3_a=X` znBmCQFQXZ^datpG^Z%J)=6{v1b@xNZWP6QsYEAzx_6PqdruTe+_D|ev^t@)*rEQmr z7u$mSmZ|W+li+`^MSGB!bFcBJ;-!6ODqeFHuZ7^X0K7OKB1eUauuOv6k3{wZv|$CH7%0aR71jKL&q2 z4}UpfzD|GBp0Bwsz*<7a#P^~7z9{9(n)@L7_n#rndAJjJ@?tuM^jDD9{qb8m_Fc|? zJhJ}SiSoP97j~mB?1NkfhKOCCm3!9Bi+7u~K(8r|+p>vq?8wmZ|h-I>Ah=jrrxr zlD~W|27fwm-MH~5c7NqQmwM=aJuYE=S*YlISYL9l!1X2l_D@lU^A-K}Pmrb^P6Ds% zq~F$j>9@7r=(p+L2F+J$Z%lucYQCcFP73>3=*6rvX{S@@qi4nR9y|-{IX}cWVQft6 zdmb`teK|jCeNO?e_2oKK>&tZ}_0{Xlr24A)nLag@zO+TEb!O!#VxgnaThCWV;UC^S zHMDZsLaYkN=@hs|$7bSu^_b#C8xH5UNTdB0)7o!oJpC5a+HWzf{TBRA_u>D-`D!EPVeT(~+xbe5 z!yP4KJ70C9KW_ZN(EagaD*sZ}GQ+b$Urx(6l7}F6u2qMmsI%aSrTa?ppaPA^+ z`WVfd@o*>aV#PZTKEVXcZ7H3&!X5yBb{&k;|9;SmzCb0vC%sZ?~)|0GxWP8Y;XN8 z$%ob6C1cdyCf+5vto0tF_Rhz0OMtt=9W2{G?t_Gp5mzo)_OBO{T}f2&4-cJ`v>m3lCGymxPQ>=75n|Mk?pTX!`|L!$8PB}b`^3vl?<&XsSdVAw{XcCy>-}(EZ*}1N zFAcr_cvj_WAC_w0$^J6jez-vK(mpU1uL~pC55Ic+((Q-$C|>l5!|jVm^Ix$acE0Cs zB7Vnrxl_IG+qte}i78fvxK|?`=(|g>?;h#!>oe-AVtbNxtu50s_oobOC>P52%7X8jJ*3({xXd%SNU&3zsBc)E{pkHpklBJ#cxnZ@}^U53MKX zGVX0IiJqO8ho0QCKd0j2W1{EI%R|p(zwgj%6WyL4=6H>c(RfYv`;N;=@1il%Td!3P zVXZRbTSKo^43)2aR;qnA#|iiBL;b#^^_zBG+SjMzm1_U*e1=`1c)f>tiE~9NUa9u~ z&fj;udeoMSzJ9p96>0R|ifO&K(s(}0WZJxhzwel+-o5b~+j{ei{k^8~d~d#SrneaH zZwK)Hb_w3SDaX4vzl%9fuMcig>3x`Q7OVGd9z^;s$GbO+jWfH-@Eq?}V|vdz&`0qs z?+5Go{>YpTzL!1RyEmlK@7^%YcW(&!?hPT|y&=@^-Z0H~Z@REP(DLnqOq82#*pBoj z$WjG4>Va!Atiap1i1tHxzvwW2n|&1ToOh|ekpR7WN5Q;$51cf2?bwK5dCxyX^-RG z_sx(4`Fm;sPXb=?clO#4w0kz;-FM2vzwv;-*(BwHtk82Q^bGbK!@KV%@b3F7;!O8x zy!$>Id&aAgN1K?CVGd}V@3epO+cxifymLf5YPwYkbbAyX^xQK|wflMSyB=kN5XTASrjP&L@=5p5idzmADMn0N;&UMV?toOf+k=}Y8a|-L2PkwFa zb<84_uYFvq^#bjf?438~yLe9@w(HV9G8M1Iir1}}W6R+0ImafxJ04QJw2w{2>n_Es z7Q8ltS5)zGu4ArHyx4b!TgQ+_uVa|j>llsaI)-Vzj$vBAi-&bc_xX!>7w=O1PW9V= zGqRY=LyFEBbKzXZm<#8=BaXf5A>j4;_7SA@`gAwaj6WpKX~GeINIs{H?72DDi6f1v z#NgYw#^yU(M;&^M=69Zh^q6b!KR>MB+j1`cZQ8;75Zd8V{N6UP9nAm2cF@1K_4QQ; zWg`fLA=Bts!mY-I1PCs{E`3GmrRlgUh+j7(~*WdPUO^xFH61L4q{bI7eMWf#j zWb8`6ANXPEy?l)H<{Dqm2fDrWo{oC!_vAh-y?2h0-pOK>dQV5aKlHyvlQHr&{%HDn zvRGxO+RIXJy@&s>+WXiTwYOg52QXi?K0fq(wNd438>E_JMlxT$bnw#6R~?GiduXTM zHdZ-b@nYY(9Ou5!1^aKmR(ZGeKIj$xJ3Qk2Zp6;^-8LP6E6`kYK*i1uAubldJ^o(A z!~D&{KHQstj{tgYx;@16?@O@UQ>xq%1<{5wCWqLZ)hfRyJARqmXE?|m@40<%D1cXpo^E^t;%b=9!R)9oN(V2 zug`uTuF4z4nBwoP?Z1Pn){PJU=t-`{?neI=Rr~C}%L((0-Bx+kmU`?at^Y*16eL0b{&B%FFi3(mZPZeS>T$y+X5K(19!{3d%auNVJ=Wv2JEp*r~GZXb0!>1=y$uzNhCM*mZ-kzxyuZ`R*FyOm~A} zbv};Y;_E(I;_3H2l}g4G#ozW+FXSBjXI^Y0L2J}>3-725hq*g1r`(AiGA(a+Wb z$9{&g1L_i}%ZIXl)Row0e-D4BsL4CBe)jXP+U?O4GP9!6WR{>(sotKcA%5C zs|RF11O1)@)Y~y;o&Br{`Rr$Rp`X>DpEaPL#XQ07ZR=Oczd8Mp7ok67p{{mY2hr9T zlj<2)vOa=2Zh%dWi|Kq;h2NkJ_9@TeebZz%L7Bdj7<-rx`8Sj0*!$663~YyeXonXi z4u30L*`-s#T?+1oezX(vrJdT9oj@n;v=fka0{xytL)hs-je7NE9hIN(YM}kjKLnf8}aJ?f%0`hzL$V|3iIYr?f#V5-+e?p z-~F68(|ru{=KN=@)q7A*_GS3DwI{9B+XwKjkiO!$T7MjcFT>xJT-5JBxNgC^Q`z9W zg1rg~uidASFKu#8*#vabChq{!CZHd3{=0yD%GeE?oQF+%VH4q1^WQ&NtKox_%9ZA| z=j9v)rzkj0$%T9=m(Od@%b=5T`2i^x=!f)|dB~?+Y2N+aIo{{Hr+CkFPxJQs%b!1Q zt=>1Ftt~KtH5^x)J%5%Y#Cs>l6J%l=E>>K|-fi8#LAffgJ$E1Q zj{ffs>Aye2Z~oYSmtlV|zqhkn%|U?M83Qr#T!(*~wjS|<6%W~acz)yHsxR7Ut~L2> z5bVR{I-*q3kY_#iWFoC9(8_U$-^t+Yp8X3u4%>$L?rzMJfOv+t40G_@0pAv4`A(GI z0h+rd%?i-i-^tkpS+?%A>u38`f$m29ogu&h-}ab-^-T@FH$goAra%qonC5pnSf&bj zkWqe%;uyYRMA}Z=x2>w^xDkK%<^CTPY~(i^?C<%^>^MBkGdi}h^SeT)tkC;st?lo( zee`eJ`3)xf`%Et^ZM&wUoxdTnte-43@m(hKe(UD8nUAzr_I|L9-(>n4-cKt1g576Y zueG)nLl3r7FTT~3CBD+r_OIb>ZU44&TiaV--RArrlVw>S=eLh4)px2;|68d4E&UB9 z{^rQ>4JL>yj86NbaaEL^-t~F~46w%i6KTy#K)-t;at@=6vX3S##$uhP-?? z+?Lt8xdb|~EcrX-?X&jd8R*=(=O8m^%23+HnW5a$7$&bDJaJO-T}Mn6OKRd~-R{@o3yjrM*@eG;(6hFuC8!v1>S?D^FcU(7CE zP-EU?-X5+qXSd*kd9!OIT9`Hv$cVJW!p)}qvSBC|X^fh+p-4km(M4(-T3hOGGUJ~> zRORyRi~{pkNo-a()`ZQva5UU3dBi`>cW0fat z!)?u!cAgo+*A?pl?^_d&0^DnZ=5XD*=0@I!8d}2@TejE&-M(U_Ox#h5FXZ5;oLzGh zG@duRdfx0B`@fVaF3;LKMkG(1{>~ARi#UB*>4*x%>DO;88%cpUec8GdqoOZezI;^l zWh+O=f9=K*HE>-1+eade=(p$ciV-zfod2@5l_RMkPQQL+0f+rurb4KZ^z2i@$Nal*L9d-HkVKZ5fhXLYz0|DWLv48T_aYXA@LwX9u$ z?GIVjA;1%W#{s*(Xj$EWHD9tUABOcYzCl zlX(TO{p*(13wYxIGc>9n=eW5O62pBXCyuot#+nvSpnB?ESuFod@iC z&9bJX332G(EGqzb@Mo5F7vKeay{{9n{yob&2$+u<c;Tx9F6=iCeUzSxW$}&o)Az6&GeYa&bNPKSPexr2!^z|r&!^ByM^EmR40g795 zJB^8@_e+}UewrAv>S5p0EOl${?l_GnB8gbfKAh$kpd+AIo?9Y$*x7>lM{%A&KI=n% zvCLm(*TMW#I4>ao9p>MfTcX8i1PSwdah^n59%TM&-mfVQn-ewnJjvOgaI zNU<0BvuqtIHUG~j{+oc`hd!}^?F(+1urJ*;ozb)&iUDx4$ zKBl4NnF|^}CdQ%oRD$M>XDuslysXQ?C*UO?+CB!FQ!gmn>b6}cMG+?Q_aZ;naCL{Ta);zz^vTXwR?3X&OLN@>9#&lq+ctWa>`i-6d^f0=*kFv3KAr?6&H+ zpJ$CU5XavU&^-4m%Q}LzSb?$m=jo56Eqm1a70!mw#mZcWsT3g#%-nIZg4j#u~3#q9eub>HN%?|=1y z)ksvAx=&a6#c6hahPpqi^2e$BKU6SV!8`@8P*4M}P6&^b$D{5|CHNF|pQ+%L3g)NV z_2agQs0JlJ_{n=kCUm)8C9h9q6f2mepqB3g%hvalqK7@D{@RY`)&1Y7d|l6&!ELr( zQt|IrdZ)^F@xPq~RxVq1lbOGA-NpiQesR%)BHeE^*SSd8eb(+-B|f`fF4qJJaGInq z!d3UgfdqEGg<+UHf3YmT6vNQY*W;LS@X+H}j~g4?f3@We#mkEpTi%oXBm+`*eeYqI z+x0!C{Dxmqol^Zz-w!B^n>jd@edG`-QTExXAn9l0+Qd>MMD3Civ>T0oz3BgQkc z>ApOMZxvX1JeiLZq-B|3Db}Ba@Cae z1f9HGJ*Ao8JT7T7CVd?sBPZ?0X;~IhnIW)BJDryMceoLm_wnvk`z|f>b>6*Z-}!{E z3KgcEN%MXel+Y}II6u83TY!X@Le9aR$Cq{`fj?~$K=!{NFKeFv4@hzgc&1O2 z3g_GdhW?DN``SP>eiCjnj-)R~T8w`bR2k2X>mU=6TL~a*`aBY{rtxBek61r36Q`kQ z?mna@_;~gI1(7i#pO#2o{of$+DEQ{SAd$TKPZ0SEkw273Uj47*lCy!bW&WqH2$|#G zgiM+5DA|4mOy;j9{1615@nO(rzB}bP+@y`)#GJm#cggXQdrorX)qevrCf$w8v`oYB zeSu_u#EaLkd1eZ-Ni%GwnGdkKbR(Bdm6j>VGmI-r$u{#v=4IM>c_NqQoZ#ctzYmv* zoDOooDv`YUpCDy2?^VRGb#OD+LTK0UTMb?*bAy)Ru z2_lOum?Q5qMHU;7%_i@?B4;n9%sk~|4;ep>T+d|vn-n68PN6}QX2NB7j)C|J(^r;z zkks!Z-?u!MV^)lhqNs0$Z!$p6_#I&2yEXesQ29k}3qaPNfasf=nO96*MUs_XGD^$x z!WY>Nk?u21EF?4Ap`8QWY#=uP<@qDr7*}TBg!?S7uhlN&wH;I14Zw}#?d#)3$i|sw9oeiT$TIGeu?T8P6z>&{Y!{u%#-PyUlLzs zbg8LFPaVc1<6k2c{FBN#f|5LpM;?Umxv$9FsjL|(dE~w=aWg5%GMr0r=CZww<;BE3 zg!4~vPWTb&?(~-+{U*-War!G&HM9Va`%%fnh%h!yAZ7;crsJH{uE-`E>ph}?A*!7 z6vjjYscd5WSnGObiR|oKaEn1SRd{o6%Dy>!QFg^-uu?ggmeVJI2;O|Mk(~{K^hMbQ z2r|dp^ti2<96-KLF^~u}qhVA`CgHdlqGIwq5MgQIu+OAS7MX}_ zpYAX!d(s0t3=qH#|M3n(c=Gm?!Cq5<6cdg4D02mcTYObCS2LCdPqf|d1M3wx9MMd*kwzkxSn_A{IHQpC)ZmQOBAqG`TEYut;T2D%JK#yJwdb@;CeBBHj zvu4ipV5&CWM!r{cmZEXs-6xCDGmRJo|iiJ3%Kwu;*L~B0=RU->-r=_v_o={Cqvm(S@ zIEFM_LWG4e!b6)Qh0(@XxTu;oh&8YhtggjOoL<2>YLLb#8;RNUA|}Z=V+F@v_hZidHz<5VRC%CvDL%$Pqp-DjjvMX?OSOvj|3=FM1= z?vv0+HzjOIpGpWC8_lcC0i!94&5Zx!9cOsbU>Z(>UU6}@kM`SMZ=t*e2F$LFt~XNN zd2#Ge4LVN`r2*EDZE2d<(p){S4h>LUxS;5U8=T4NmR5nCtXaC=MApKh`SI==jI=a5 zZla;)CJ_v>gWs?q7!xg#=)z!aL*spsXsv^;HL8f_FCmn_&a5M9RwV^GMhOJ^nL+!#FgLgJI*NA9+jm%mYYywvlqXey@ zp)p!#)-<+mZV30+5^b^ZGL!YoguJvyTOxJQaE%lT3M~wBaL!+-%xVhhK9oG#weOI8fyWzxv@10e^ZC5WA&s0C=53@ zM;md2ia}U?PhnFtTu61Su^CACkispEHQ|OO97K^&Lt(frTrFBc%C1l{ZinjnkZtl$ zhnpKkG)SdeKHYCim>Jlba7#6@wqfknx0^_&X+yHF3B^LH+2a)qX#bi95iDzLY=8rk ztY~iKAcNt?C~Bgc?Z>q(_?YYu@iw=+A4(I$(psnfG9mU3)vz}#aJttxIsgi^V=xw~ z>n|6Hs{Xc4b~Pnde}0I<&=4Y6aa&Nj{9tQKxQ26BEK*(Aj4n|Pr#$2!RZf@PHxdhm znwvvg!3uLA)ckZ93WcNhHaY!YFvyV`#7GU+qRi#qA1f=Cjj~sUn(NRtp*-3ot}3k~ zkaI7P4oiijHN%>he${#0rfv+eUMG(zRGRpuv3|dkcyL;mF~kO)+#BcEpp#CH8%E4= zqvp6f&hZ|dbaLD{h$CmhN>ylsg6Y`T+;IJVeOsl_hG_gco8er&kqLDX9@irVjzB;a6He5XL&`os8V)|BauLu zL!3>DA0LnZ4y4Z&$?WYF6U4qY6{&C(@B;PV)@1mJ!u*Y)_v`TzUNK1&C&f<|B}ws9 zgs_tF;nShP&pQxa!9$&7_$x(cQatyGgAcF3CM(I|6;~(0($3eUz%xoe_^_An$?y#0 z3_iSK`XD5SdYbr!m6(wO1U78(er_rP#;KCgPepz*{OlC?V&Jg}9MrzINc`aTWe~OSBN(cg~LpT}o$62D8eul@8v2*%x5Z}GT+d{XK4 zWyxov$WQ2pe<|^Pv9n_!pJx^SvnuF=TY3CHT$9=JHQ*`dUL_}Xdh+-Wh2NJT{|CT( zFn$*+`MIaykpac2SNV8bo)b1&T%+()a&5ex2Id3Ldb<+%->mS*6Y#6Z2lZZrSP2yobX=HGj{`@%nqbUhHsVp2K%coD|}a`&7b9Y98-9>&;fqt z-!-2E`dsYC5mOOW33$fqiQkkkPkln+I}_;dllZ~?f0v>+6X^e1;}hgOsqi9!o{uyr z&w&K|)d(6GVz8f_2|Vdb66kN0_`!01QsM{u^9IQu{x;z`a3ied}=OD$y@r=aVY3KFtQs7TwfS5`A`ANlpT7li}y|TT9cn$c8PR1&I9(X_a zbgF)?Nq(*PyrTN;Y4t+Fqr`6>JU^yG9_n>tsa@}3-1C?s@pjsIos|N=Q1LmW#`Q5( zXsN<4UOG^(bsAr7<2NC~%VUGWH)Pv*KEmO#S>o-q^SVvZPx+`#e-!sT{seHMXOajc z_`N?@^e5&Gl;^J${-kN+*C>bk4T-mTI6XBN*t9H@-hmVs?Cj*u4 zA-!j+XiI3vcO{=(p`VK2RvzgHp-rk%Hx6)x#AB9J{q~5;o2~GNr`dX$iqU5=9{rH> zWJ0}s#=!odLzBxDpBogP8s&%IQTQdmQ{UZ+k7_RQ2}S?L3cKE?ls$i6;g8L?@pSl+Pl4}N{CBUj`5#wy_;m{U>BMi&7JA>I>&S*4Y?srw*nFyV zh9jQp*yRu0qhlN15^Jrk#dbXyT(;r1+k6C z(XF?au3Zt-cl|sW#Ibo+FbZ0@rm?Z9NXBg;ZT$l5hg+g6!_jba2(=MWjZhB|8zKl- z;kKc%Zh=h~iQTS(YHLF+_p}h%9Bv5@#)ew91e+xDme9T7VE=7hIEK)MT{KeL(ArW@ zCR-4qYOHofDT?JWe^F6WLo8U0?4qV-1b%8uN>;9^C|ed>P&EJJVlWZdH-+lL-2D$j z8E%Wjh9TLaLSVy?sVIXCxrqhMV)T2>lFd^(0P+3f69!LW=v$^k;M^=pDRi1^*wjl7lWIe01yIxw=k-X6ZU zzhv3U6{rskD{6(xty>Q-5|2|kdXSTm7I*!|GSsa6i9O2WQkAVE@A&PVAao7|2Rk?$ z#8g#?P>$ca_2F0r!(+&5X$;nfqBV$pCxj$rR~x`4-U2eT7O#5k9YN_VP(7OiH7IXF z_Y!H0-nP15%-fxYEnU7`s<*kNMM=l8Bvc1>R2{EsJc=x4iZZ6#y~1~;r-ro5r@ z9Zn`{#5qyg(90|C0OR=RPeyY4iVeYHA&OeIZi$691IC(dSg%uXR(LciisXa1(z1#| zhK7p}pD(Hp!RZy%Y>lF@4P(uA&b{I07MN(jO%Qnq1cz8arQi}pk+gbIEZl~)90Nto zjk4bsh3hdGI7u+-9KRDqavDH|oDF2Xh_@rST-OK=c1f5XWQ|+4;6WR3;mxgeh$x4m zaH#rLKAzE8n>RP3gR46}a?oiQK_}_g6@}uYr`3yvjF@nVBDXt$I$j4TkHodSUN70X z_G8dY-01Q;t_LU&(+2UYTCT+JKZX>R5b^Rl{s$-z#w~b|hKG(TXg>3Sdl&Ec>iWA> zJP=SGI`WfP-p&>Bp*Y@)h}VBsl?RjuU#a84Wf_yYejTw|1{{{k@$x$E2q=#~v_bru zXus9S;XBJ({=ZT0DFezQQGQLQ;U-Y=9cX>8$;Euy|q?zPPN6zv(UJfXaxi*Mjm09BVe2a?Zwf%J57Em7c3w3sySFOLs zJcNX^ypHbz%0us4G<{- zl-F_P;t`hrTa;&0>H2m2xkQ!kqHs8L|IqboxsD;vDStdpts=6z|4JsjD1MsHy+ARo z>qkpU*2SuP6U#UbT~5Q7kmsyl@2{IwMOseHLYLF`|Ad6I{!UeYrz&5m2^CB%{|fM| zzc_(Tm!Fh?SL!S7LcFTVCy#UC6a5wI7p(ana>9{0I^{t!W5nO|h{n z5;7BRMLrOTIF@g^!p3&;#&IOtpHvAZlGNu_`QjYA@C<-ToVx#L|IOdiB$!ARFt4-g czgiDGi5)B}*9XbU-$cc5@Ksvpk#H;iKO>z1VgLXD diff --git a/CodeExamples/If-in-Loop.power.c b/CodeExamples/If-in-Loop.power.c deleted file mode 100644 index 8eabc2a..0000000 --- a/CodeExamples/If-in-Loop.power.c +++ /dev/null @@ -1,1172 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_BNE_I_I_32_1(i0) do /* bne */ { power_G32(((0x4082 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBNE_1(h2_sValue_t P0); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genBGE_1(h2_sValue_t P0); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBNE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BNE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BGE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (power)\\n"); - #endif - P2 = power_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -/* C compilette prototype */ -h2_insn_t * genIf(h2_insn_t * ptr) -{ - /* Code Generation of 22 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_endtrue_00000001 */ - #define h2_endtrue_00000001 1 - 0, /* h2_iffalse_00000002 */ - #define h2_iffalse_00000002 2 - 0, /* h2_ifend_00000003 */ - #define h2_ifend_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1F80F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, LoopValue); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0002 = power_genDIV_3(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - reste = power_genMUL_3(reste, tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - if (!reste.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, reste); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_endtrue_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_iffalse_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_ifend_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; - power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_endtrue_00000001]; - power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int selected, res; - int i, tmp; - pifi iPtr; - - if (argc < 2) - { - printf("Give 2 value (LoopValue)\n"); - exit(-1); - } - selected = atoi (argv[1]); // Get threshold value - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifi) genIf (ptr); // Generate instructions - res = iPtr(selected); // Call generated code - printf ("Result %d : %d\n", selected, res); - for (i = 0; i < selected; i = i + 1) - { - if (i % 2) tmp = tmp + i; - } - - return tmp == res; -} diff --git a/CodeExamples/If-in-Loop.riscv b/CodeExamples/If-in-Loop.riscv deleted file mode 100755 index 5080de950997ddccad7c7f5fe307bc927d298bbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41564 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_BNE_RRI_I_32_1(r1,r2,i1) do /* BNE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BNE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -/* C compilette prototype */ -h2_insn_t * genIf(h2_insn_t * ptr) -{ - /* Code Generation of 20 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_endtrue_00000001 */ - #define h2_endtrue_00000001 1 - 0, /* h2_iffalse_00000002 */ - #define h2_iffalse_00000002 2 - 0, /* h2_ifend_00000003 */ - #define h2_ifend_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7FF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGE_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0002 = riscv_genDIV_4(tmp0002, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, immValueZero); - reste = riscv_genMUL_4(reste, tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, immValueZero); - if (!reste.dontFree) h2_freeReg(tmp0002.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBNE_3(i, reste, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_endtrue_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_iffalse_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_ifend_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000005]; - i = riscv_genBGE_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_prologue_00000000]; - i = riscv_genBNE_3(i, reste, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_endtrue_00000001]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int selected, res; - int i, tmp; - pifi iPtr; - - if (argc < 2) - { - printf("Give 2 value (LoopValue)\n"); - exit(-1); - } - selected = atoi (argv[1]); // Get threshold value - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifi) genIf (ptr); // Generate instructions - res = iPtr(selected); // Call generated code - printf ("Result %d : %d\n", selected, res); - for (i = 0; i < selected; i = i + 1) - { - if (i % 2) tmp = tmp + i; - } - - return tmp == res; -} diff --git a/CodeExamples/If.aarch64 b/CodeExamples/If.aarch64 deleted file mode 100755 index 2f4562fca1e54a3befcfe92f377923e76ac5ab8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44024 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 diff --git a/CodeExamples/If.aarch64.c b/CodeExamples/If.aarch64.c deleted file mode 100644 index e3f6f2c..0000000 --- a/CodeExamples/If.aarch64.c +++ /dev/null @@ -1,1117 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_NE_I_I_64_1(i0) do /* bne */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0x1 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_NE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -/* C compilette prototype */ -h2_insn_t * genIf(h2_insn_t * ptr, int selectedValue) -{ - /* Code Generation of 12 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t value = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t threshold = {H2REGISTER, 'i', 1, 31, 10, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 31, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_endtrue_00000001 */ - #define h2_endtrue_00000001 1 - 0, /* h2_iffalse_00000002 */ - #define h2_iffalse_00000002 2 - 0, /* h2_ifend_00000003 */ - #define h2_ifend_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0701, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - threshold = aarch64_genMV_3(threshold, (h2_sValue_t) {H2VALUE, 'i', 1, 31, 0, (int)((selectedValue))}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - value = aarch64_genCMP_2(value, threshold); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_endtrue_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_iffalse_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_ifend_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; - aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_endtrue_00000001]; - aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int selected, toTest, res; - pifi iPtr; - - if (argc < 2) - { - printf("Give 2 value (testValue, testedValue)\n"); - exit(-1); - } - selected = atoi (argv[1]); // Get threshold value - toTest = atoi (argv[2]); // Value to be tested - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifi) genIf (ptr, selected); // Generate instructions - res = iPtr(toTest); // Call generated code - printf ("Result %d = %d : %d\n", selected, toTest, res); - return res; -} diff --git a/CodeExamples/If.power b/CodeExamples/If.power deleted file mode 100755 index c5bbf4e813375810a588d6bcb1084fa5896efdb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78264 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 Q^+8deUTHO7Nm=&)0PCebUjP6A diff --git a/CodeExamples/If.power.c b/CodeExamples/If.power.c deleted file mode 100644 index 41cb10b..0000000 --- a/CodeExamples/If.power.c +++ /dev/null @@ -1,936 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_BNE_I_I_32_1(i0) do /* bne */ { power_G32(((0x4082 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBNE_1(h2_sValue_t P0); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBNE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BNE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -/* C compilette prototype */ -h2_insn_t * genIf(h2_insn_t * ptr, int selectedValue) -{ - /* Code Generation of 12 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t value = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t threshold = {H2REGISTER, 'i', 1, 31, 15, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 31, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_endtrue_00000001 */ - #define h2_endtrue_00000001 1 - 0, /* h2_iffalse_00000002 */ - #define h2_iffalse_00000002 2 - 0, /* h2_ifend_00000003 */ - #define h2_ifend_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF80F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - threshold = power_genMV_2(threshold, (h2_sValue_t) {H2VALUE, 'i', 1, 31, 0, (int)((selectedValue))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - value = power_genCMP_2(value, threshold); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_endtrue_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_iffalse_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_ifend_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_prologue_00000000] + 1; - power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_endtrue_00000001]; - power_genBA_1(intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int selected, toTest, res; - pifi iPtr; - - if (argc < 2) - { - printf("Give 2 value (testValue, testedValue)\n"); - exit(-1); - } - selected = atoi (argv[1]); // Get threshold value - toTest = atoi (argv[2]); // Value to be tested - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifi) genIf (ptr, selected); // Generate instructions - res = iPtr(toTest); // Call generated code - printf ("Result %d = %d : %d\n", selected, toTest, res); - return res; -} diff --git a/CodeExamples/If.riscv b/CodeExamples/If.riscv deleted file mode 100755 index 62e286418223b85232c55e7190ee2e47f770e5dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33272 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_BNE_RRI_I_32_1(r1,r2,i1) do /* BNE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BNE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -/* C compilette prototype */ -h2_insn_t * genIf(h2_insn_t * ptr, int selectedValue) -{ - /* Code Generation of 11 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t value = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t threshold = {H2REGISTER, 'i', 1, 31, 6, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 31, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_endtrue_00000001 */ - #define h2_endtrue_00000001 1 - 0, /* h2_iffalse_00000002 */ - #define h2_iffalse_00000002 2 - 0, /* h2_ifend_00000003 */ - #define h2_ifend_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x77F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - threshold = riscv_genMV_2(threshold, (h2_sValue_t) {H2VALUE, 'i', 1, 31, 0, (int)((selectedValue))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - value = riscv_genBNE_3(value, threshold, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_endtrue_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_iffalse_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_ifend_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_prologue_00000000]; - value = riscv_genBNE_3(value, threshold, intsValue((labelAddresses [h2_iffalse_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_endtrue_00000001]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000003] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int selected, toTest, res; - pifi iPtr; - - if (argc < 2) - { - printf("Give 2 value (testValue, testedValue)\n"); - exit(-1); - } - selected = atoi (argv[1]); // Get threshold value - toTest = atoi (argv[2]); // Value to be tested - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifi) genIf (ptr, selected); // Generate instructions - res = iPtr(toTest); // Call generated code - printf ("Result %d = %d : %d\n", selected, toTest, res); - return res; -} diff --git a/CodeExamples/Loop-in-If.aarch64 b/CodeExamples/Loop-in-If.aarch64 deleted file mode 100755 index 3df33b82cdd3b6517771f56b22b17b0e27196c6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52312 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 diff --git a/CodeExamples/Loop-in-If.aarch64.c b/CodeExamples/Loop-in-If.aarch64.c deleted file mode 100644 index 4eaf1ce..0000000 --- a/CodeExamples/Loop-in-If.aarch64.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_GT_I_I_64_1(i0) do /* bgt */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xc & 0x1f) >> 0)); } while(0); -#define A64_B_NE_I_I_64_1(i0) do /* bne */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0x1 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genBGT_1(h2_sValue_t P0); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBNE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_NE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genBGT_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGT instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGT - -// No specific optimisation for BGT/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_GT_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BGT instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifii)(int, int); - -/* C compilette prototype */ -h2_insn_t * genPlusOrMul(h2_insn_t * ptr) -{ - /* Code Generation of 32 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t plus = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - 0, /* h2_prologue_00000008 */ - #define h2_prologue_00000008 8 - 0, /* h2_endtrue_00000009 */ - #define h2_endtrue_00000009 9 - 0, /* h2_iffalse_00000010 */ - #define h2_iffalse_00000010 10 - 0, /* h2_ifend_00000011 */ - #define h2_ifend_00000011 11 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0F03, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000008); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - plus = aarch64_genCMP_2(plus, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, LoopValue); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genMUL_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_endtrue_00000009); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_iffalse_00000010); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, LoopValue); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_ifend_00000011); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_prologue_00000008] + 1; - aarch64_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_endtrue_00000009]; - aarch64_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - aarch64_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int plus, loopValue, res; - int i, tmp; - pifii iPtr; - - if (argc < 2) - { - printf("Give 2 values (Plus LoopValue)\n"); - exit(-1); - } - plus = atoi (argv[1]); // Get operator + = 1, other = * - loopValue = atoi (argv[2]); // Get threshold value - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifii) genPlusOrMul(ptr); // Generate instructions - res = iPtr(plus, loopValue); // Call generated code - if (plus == 1) - for (tmp = 1, i = 1; i <= loopValue; i = i + 1) - { - tmp *= i; - } - else - for (tmp = 0, i = 1; i <= loopValue; i = i + 1) - { - tmp += i; - } - printf ("Result plus = %d, loopValue %d : %d (%d)\n", plus, loopValue, res, tmp); - return tmp != res; -} diff --git a/CodeExamples/Loop-in-If.power b/CodeExamples/Loop-in-If.power deleted file mode 100755 index 1b3810cab7df8590800027ff37bb0de7ca07b409..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78352 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 ML9fbM58JKyZ<$W?E&u=k diff --git a/CodeExamples/Loop-in-If.power.c b/CodeExamples/Loop-in-If.power.c deleted file mode 100644 index 63df0f3..0000000 --- a/CodeExamples/Loop-in-If.power.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_BGT_I_I_32_1(i0) do /* bgt */ { power_G32(((0x4181 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_BNE_I_I_32_1(i0) do /* bne */ { power_G32(((0x4082 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBNE_1(h2_sValue_t P0); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBGT_1(h2_sValue_t P0); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBNE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BNE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBGT_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGT instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGT - -// No specific optimisation for BGT/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BGT_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BGT instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifii)(int, int); - -/* C compilette prototype */ -h2_insn_t * genPlusOrMul(h2_insn_t * ptr) -{ - /* Code Generation of 32 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t plus = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - 0, /* h2_prologue_00000008 */ - #define h2_prologue_00000008 8 - 0, /* h2_endtrue_00000009 */ - #define h2_endtrue_00000009 9 - 0, /* h2_iffalse_00000010 */ - #define h2_iffalse_00000010 10 - 0, /* h2_ifend_00000011 */ - #define h2_ifend_00000011 11 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1F81F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000008); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - plus = power_genCMP_2(plus, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, LoopValue); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genMUL_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_endtrue_00000009); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_iffalse_00000010); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, LoopValue); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_ifend_00000011); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_prologue_00000008] + 1; - power_genBNE_1(intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - power_genBGT_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_endtrue_00000009]; - power_genBA_1(intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - power_genBGT_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int plus, loopValue, res; - int i, tmp; - pifii iPtr; - - if (argc < 2) - { - printf("Give 2 values (Plus LoopValue)\n"); - exit(-1); - } - plus = atoi (argv[1]); // Get operator + = 1, other = * - loopValue = atoi (argv[2]); // Get threshold value - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifii) genPlusOrMul(ptr); // Generate instructions - res = iPtr(plus, loopValue); // Call generated code - if (plus == 1) - for (tmp = 1, i = 1; i <= loopValue; i = i + 1) - { - tmp *= i; - } - else - for (tmp = 0, i = 1; i <= loopValue; i = i + 1) - { - tmp += i; - } - printf ("Result plus = %d, loopValue %d : %d (%d)\n", plus, loopValue, res, tmp); - return tmp != res; -} diff --git a/CodeExamples/Loop-in-If.riscv b/CodeExamples/Loop-in-If.riscv deleted file mode 100755 index c7374d89b230df7d3a738d6bd8dadf608f2156ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41540 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 W%B2=fr!2mFQ{Y^NshP-AqyG -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_BNE_RRI_I_32_1(r1,r2,i1) do /* BNE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_BGT_RRI_I_32_1(r2,r1,i1) do /* BGT */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBGT_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBGT_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGT instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGT - -// No specific optimisation for BGT/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BGT_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BGT instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBNE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BNE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BNE - -// No specific optimisation for BNE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BNE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BNE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifii)(int, int); - -/* C compilette prototype */ -h2_insn_t * genPlusOrMul(h2_insn_t * ptr) -{ - /* Code Generation of 29 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t plus = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t LoopValue = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t reste = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - 0, /* h2_prologue_00000008 */ - #define h2_prologue_00000008 8 - 0, /* h2_endtrue_00000009 */ - #define h2_endtrue_00000009 9 - 0, /* h2_iffalse_00000010 */ - #define h2_iffalse_00000010 10 - 0, /* h2_ifend_00000011 */ - #define h2_ifend_00000011 11 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000008); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - plus = riscv_genBNE_3(plus, tmp, intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genMUL_4(tmp, tmp, i, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_endtrue_00000009); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_iffalse_00000010); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, i); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_ifend_00000011); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_prologue_00000008]; - plus = riscv_genBNE_3(plus, tmp, intsValue((labelAddresses [h2_iffalse_00000010] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000001]; - i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_endtrue_00000009]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_ifend_00000011] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000005]; - i = riscv_genBGT_3(i, LoopValue, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int plus, loopValue, res; - int i, tmp; - pifii iPtr; - - if (argc < 2) - { - printf("Give 2 values (Plus LoopValue)\n"); - exit(-1); - } - plus = atoi (argv[1]); // Get operator + = 1, other = * - loopValue = atoi (argv[2]); // Get threshold value - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - iPtr = (pifii) genPlusOrMul(ptr); // Generate instructions - res = iPtr(plus, loopValue); // Call generated code - if (plus == 1) - for (tmp = 1, i = 1; i <= loopValue; i = i + 1) - { - tmp *= i; - } - else - for (tmp = 0, i = 1; i <= loopValue; i = i + 1) - { - tmp += i; - } - printf ("Result plus = %d, loopValue %d : %d (%d)\n", plus, loopValue, res, tmp); - return tmp != res; -} diff --git a/CodeExamples/Loop.aarch64 b/CodeExamples/Loop.aarch64 deleted file mode 100755 index ffc1bf970ff29a20201ed1a4db9ec15f29e75c40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44024 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 OhQB)@a^jp$|Nj87K&ov3 diff --git a/CodeExamples/Loop.aarch64.c b/CodeExamples/Loop.aarch64.c deleted file mode 100644 index 38c7819..0000000 --- a/CodeExamples/Loop.aarch64.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_GE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifii)(int, int); - -h2_insn_t * genMul(h2_insn_t * ptr) /* C compilette prototype */ -{ - /* Code Generation of 13 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t increment = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t res = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t k = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF1F03, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - res = aarch64_genMV_3(res, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - res = aarch64_genADD_3(res, res, increment); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, res, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res, resultOK; - pifii fPtr; - - if (argc < 3) - { - printf("Give 2 increment values\n"); - exit(-1); - } - in0 = atoi (argv[1]); - in1 = atoi (argv[2]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr = (pifii) genMul (ptr); // Generate instructions - res = fPtr(in0, in1); // Call generated code - printf("%d * %d = %d\n", in0, in1, res); - if (res == (in0 * in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Loop.power b/CodeExamples/Loop.power deleted file mode 100755 index c89a785b7e4a891262c6f35a8e6d18d2f8fe389e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78264 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 MPp`C^kEBcX-?(GKmjD0& diff --git a/CodeExamples/Loop.power.c b/CodeExamples/Loop.power.c deleted file mode 100644 index 1b9a4c8..0000000 --- a/CodeExamples/Loop.power.c +++ /dev/null @@ -1,944 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genBGE_1(h2_sValue_t P0); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BGE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifii)(int, int); - -h2_insn_t * genMul(h2_insn_t * ptr) /* C compilette prototype */ -{ - /* Code Generation of 13 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t increment = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t res = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t k = {H2REGISTER, 'i', 1, 32, 17, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3F81F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - res = power_genMV_2(res, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - res = power_genADD_3(res, res, increment); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, res); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res, resultOK; - pifii fPtr; - - if (argc < 3) - { - printf("Give 2 increment values\n"); - exit(-1); - } - in0 = atoi (argv[1]); - in1 = atoi (argv[2]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr = (pifii) genMul (ptr); // Generate instructions - res = fPtr(in0, in1); // Call generated code - printf("%d * %d = %d\n", in0, in1, res); - if (res == (in0 * in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Loop.riscv b/CodeExamples/Loop.riscv deleted file mode 100755 index 796e54d3af574ca78bc1f529ba4699421095904a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33276 zcmeHwdwdi{)^_)FCld&UKu~nmWy~a8h$ONt0Sw9aoa*k$BtS@b+28m5 zVMBG*sXnLboKsI#SJia7UyB<&kmq?$KMdTzIij-sc+pLch1{Ate1mLYvFt(p16*HnV=vU6GET~02`?r>x}IQxWD7iA=kO>}UHuFO;}JuxjUGl{d=(9}sb zrz_FnvZW`cW^n0Qj!c(53G9y44A&TNu=cl&NgMARYfDW^Od4zFNQi*&7#BY{A$EYR zr=`~;4ar^*N=eHcotS3J%0wY{M;H`E>-zrV871IM?Q7st5fh&1D0yoxAR};2q$zI= zqYd1vbP-2b7SH)<;EAL(fdfZ0r3qj-x>K5UNQ?uNR^7}!PH6%pjz3YFfr{f|C{4=X zuu@tB;vh(f^?ruVMY>E4mcay!Ry zT!>$G{OfVUxR7yt{p5jseA~SFPa0;<8^>|8CqESN`Xt1;TPKGgBn8xPv*E?br6Ji{ zC%>Ni`XstC8|io7oc&FB%(cmz-_FjSzoRiv{|=!ZxpZ=l|IR6AUU)J)-t7K4XLU@d zwLky*q^;{Gjtf1+-D|cK)tV)-u1BF9;i=0unkA(UscYG}W{Xlwsqbs(O26!$BjXZZ zpTu|Y-y6Dz3pPtdb>^@V@Ve{fe?c4}-*k>4>RRW`*?qE)KS_DnZ%i(oZLBohS2)`^ zO5B`%FeM~Aep&xVdG2D&XsaK}n>fz@Q0M_okLZ$GbCjp{TD&=ww6Il+;wuIz%}zOaWBkZ zIom0xuiDPJsxQD{Bnt(yHU4DvnOgFgarw0#=1F|cwP*WfH?)(E7L=7orF*WedA24d z`wiWz^Q-iFfgV=x?9!V0SG2ly3spZk&B0~=jtt)7j0`R_OUcl`Q@uGBnk#gopl##j>* z@=XM1UV1!la&NO#L@2N8Wvm8fJ=dzcE9X{{p3Gch4#7rWC|X{xN^hwP%y=uHkw-x-7S#Opa*7z4fCI z(S}FvJvH2SPb|wdM_%ECQY*%Xnf^%+)&x{oF$x%x%FYDjTeIVnI@JUe#Oyjrl54Ak zC2ct5{jSDeUXs9v%!}vO8>{(OX5cD6du|Q4KDRyh%ZwLhyq)sGjDkV4=l+AsPMMu+ zy!^|IZ)b#@{v$6h;it~diRa9PUrp_qn-4^JewCMsoUqi&hdgdBG;;7S zXD&imjIb188NzZS>hk>R7q7NV2oPa@{fwShO4mYwjS7}}<=Ol%fW=?e#YonKw4SMG;6ta&Y+4x1%tu+3wRaqD&SSX zdkMUkz0rDAx4J*_d*33hVpvNqaP$ z-dhturEEP@5cAbZttb6n?MZLvhRmDCQ;$)56!jtSHtJK<dbF%J&x#OLRIyQL+GPdZqdK5X#M+&PyePo>ea~8 z`u7#Be_z=+ENbL}k!_#5n(!3*ckgljM?;TDhyPqLiNoEfmhLprP`%IKj#5=U^s0WR znXlhzI#d3>%T4Yzz`oX&yUzHtd(GW7{sl2>*}diy8qYC?tM`;wT6#CBZ3*_LG~lU= zSBKr24)>4_pPdxYQ!z?)sS)J}^-edx<@dA}X`$l8xT&hT+a_O}4E^-hE$)Ml^({wL z15VnPpsj0ffs(YB;IAIBfLD{Uc+ad#FVysru%|D9Jq31SR)) zd;HcjZ5c{1N5Ke6*rFD?heoRe{ws{2H9V!Vb7#+e7W0zI*VIuofnR|f8drna+=T9= z>uc0`%Jp*;8jr7=qqL$uOE;rE-)q#K3tQEm3vR1D=ly5f^XYLprHghf-oAV5kYkhD z;I4iNcl9aj-0V&sQWMZ{Hxn=eVKd2lYy5rgF#ht61Ws5?bCO-0fIG>NK@Z{%=c%~` z25bD{@@SS=V}5--%|mKt68dTmu=BNN=FrNqrs9hiikK!{YTA11ybtpWNxY1E{AJ87 zE@N(S8FP!vm|I-MO5v(Z^NRrGGUgXi%4N(iqLs@SKUV^M7R(ePJ(q=W@d{RJR|Ls@ zMV35Qga}AQSZTI$(^y2Ct-K(3-GuXVN$;|ymbK@F0vJEFhqFuw$uHk4`sSQuP3$^pt&*9rF zqM32-)~d=UfAZ-cmA3OON4$63tE@jmHnnX2>mBzh-#c~dzUZATSAKq+A+Pz_a*Z}h z*7%H)l*bV29VKhDQL<)pjK#Xp8kBJLxm1jkH($B=-ch?{-*~KCB{vx>@6hUvW^mV! zjJLmfi(BOFm3LtEb`$MxgwPhPEmd5`d#Wlw-|macW7}?x6(2lqZaIp5@c3!VQQUyb zCpQ3>|It<4jc~bo%43aZdX=C5i{Y~A=v4XSVQqBMcNIF-w9{sK`?P!b{WWb1Vs_9v zo%`~P5W()`9ctRr{rh9@o&0Uwx98!$&ArO*Rc4LIpCzvbv^z{%%t|EF>C+_;=Wiw-Q_ zzq@?z-bu6*pKEj zw_eAnbAv0|+~5kE8(d*?gDcwH;7Y|8y%&3H>s%vhnsvmy9`(FkgH&rFC~R z`*N>6RH}+#Dis#6Qm1L9E^UL|Em-&gEc^f#F2+3)`!d3kDL1%BzF7n;HLRs7-@^<* z-L-2pGpOuB_kZ7gJM1lJJ#4$SiigJwVz3_u%~sIdf!YJ>E3%qq0LX8&yU@b%zD0Wr z;~Lgi_j&d5XnJ8Mp&(`j(`zm3|DVyFyqVp)8)$Z;vA#u`sbhWVuBytaQ@(w;eGBFV z4P$+`O7iM;a}UhLZoXevRk`m7?7UtIJpocT+p(+6{I*3sLEW)y;fj9UFlpr6k^awJ zO0c(d4pLcFdt)SK{@MhIovFpK>viXFh`r3~R%9(3u^aZd7!I+=wL?Q;2SVXmhQiPE z-qHEyz2hcxj@#DkgN7LqcH6X`dz-q^4%Q9&$ZhMU?n~tEsj6JH+P9DF`?xjtxvCYn z(?@13`%mAo_zt0a)n6ZdQT0$ti18o(`P+G{Wju8b_RC@j&*zve9VVEgCr=0w`IoTU zH61I-TC5~%v68ICO0o_sN%q?r{Q^qsFmpSl7Izf%Z%S>8QF25a*op;K^`WTYf6-ST|A`zkxq7f|OB_=H@mzb8I zV0WZ)X+FtOUbI4z3M3UsDv-o}JAwtlq)GcL3OFMbg-J&#%DW^-c@~8vFGBJnB(aW0 zuppQq9V&t!UJFnzf-_3F$fTo{i$9Yb<(VKIDON+W8j{tJtcK)8NM3|a;D>Zur5c>k zN;Q+VDAm`Vg&fs(0WudLa{)5dkg0}DHM9XIYv~J2zY9#x#Ngp&O_z`WG+DF z0%R^g4{)+JKF>5$Z>Y;7F1Pc7DE0UzMyh||8KU+pk&F>+-Crp1@X&-qKmUkZkztT)V|MN`dT zB~#6kXDWW7o@$OdH5Fw{y{W_$NaR5x4-$Eh$b&>4B=Uqv&pGU|{D?i49|g(%qbzxT z#2yQF1FYn|T*&1>E(dZskjsHw4&-uX`-?f)JITY|$yC}q8JLZo_HSVKS=fCRcAtga zXHmjA*nJLuRjqEToQ2iV%2}lq>3 zeMS!VoDra>ELqPA5$>}XJIU@h;kjw>+%&V~nFh~IgXgBf@@eqgG zSbqxEpMvCRSbrMUpN93P;ZfE0AmtQnH)*zqDyP4sQHeZu0y3u{a|$x2Aae>br{GcI zwXH{)YSoPhNwVEqYLe*)H@fb}QfQPp;X zasr+RBToP|l5*lJ8s$i)5;B#Lsf0`=WGW$336EBSKUAq?o)ZvK|*A+_Xb> zytSUIdKcCoh4n{a{ZUwd6xJVw^+!>XYP-L36t+hyN15$W%F%<=cS+_5WR5`Q2xN{x z<_Kht!lT45DMz#s?g*$TqTsn`
BRlul8xATv#1Ru+on1qiOf ssrsL?|M`HWsF)Y1yg-zHPfZ*gnl3A?FEW+Ch!lfkl?Zs8E-6X&Uu4~~IRF3v diff --git a/CodeExamples/Multiple-flt.power.c b/CodeExamples/Multiple-flt.power.c deleted file mode 100644 index 2b58444..0000000 --- a/CodeExamples/Multiple-flt.power.c +++ /dev/null @@ -1,1157 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_FMR_RR_F_32_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); -#define P1_FMR_RR_F_64_1(r0,r1) do /* mv */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x90 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define PPC_FADDS_RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); -#define PPC_FADDS__RRR_F_32_1(r0,r1,r2) do /* add */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDFP_RRR_F_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xa & 0x7ff) >> 0)); } while(0); -#define P1_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2a & 0x7ff) >> 0)); } while(0); -#define P1_FADD__RRR_F_64_1(r0,r1,r2) do /* add */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2b & 0x7ff) >> 0)); } while(0); -#define PPC_FDIVS_RRR_F_32_1(r0,r1,r2) do /* div */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x24 & 0x7ff) >> 0)); } while(0); -#define P1_FDIV_RRR_F_64_1(r0,r1,r2) do /* div */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x24 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define PPC_FSUBS_RRR_F_32_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x28 & 0x7ff) >> 0)); } while(0); -#define PPC_FSUBS__RRR_F_32_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x29 & 0x7ff) >> 0)); } while(0); -#define P1_FSUB_RRR_F_64_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x28 & 0x7ff) >> 0)); } while(0); -#define P1_FSUB__RRR_F_64_1(r0,r1,r2) do /* SUB */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x29 & 0x7ff) >> 0)); } while(0); -#define PPC_FMULS_RRR_F_32_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x32 & 0x3f) >> 0)); } while(0); -#define PPC_FMULS__RRR_F_32_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3b & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x33 & 0x3f) >> 0)); } while(0); -#define P1_FMUL_RRR_F_64_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x32 & 0x3f) >> 0)); } while(0); -#define P1_FMUL__RRR_F_64_1(r0,r1,r2) do /* MUL */ { power_G32(((0x3f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0x1f) << 11)|((r2 & 0x1f) << 6)|((0x33 & 0x3f) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FMULS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FMULS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FMUL_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FMUL__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FSUBS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FSUBS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FSUB_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FSUB__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FADDS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FADDS__RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDFP_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FADD__RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_FMR_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_FMR_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (power)\\n"); - #endif - P2 = power_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_FDIVS_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_FDIV_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 2 floats and return float */ -typedef float (*pifff)(float, float); - -/* C compilette prototype */ -h2_insn_t * genAddf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genMulf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genMUL_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genSubf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genSUB_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genDivf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 2, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3807, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genDIV_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - float fin0, fin1, fres; - pifff fPtrf; - int resultOK; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - resultOK = 0; - fin0 = atof (argv[1]); // Get the users values in1 & in2 (flt) - fin1 = atof (argv[2]); - - ptr = h2_malloc (1024); - fPtrf = (pifff) genAddf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple addition of 2 floating point values:\n"); - printf("%f + %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 + fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genSubf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple subraction of 2 floating point values:\n"); - printf("%f - %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 - fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genMulf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple multiplication of 2 floating point values:\n"); - printf("%f * %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 * fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genDivf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple division of 2 floating point values:\n"); - printf("%f / %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 / fin1)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Multiple-flt.riscv b/CodeExamples/Multiple-flt.riscv deleted file mode 100755 index 486b1b0c0bf1e0d02a177de8d4b3b6ec112d2cd4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57932 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 HdGP)p5+gFr diff --git a/CodeExamples/Multiple-flt.riscv.c b/CodeExamples/Multiple-flt.riscv.c deleted file mode 100644 index 1355b01..0000000 --- a/CodeExamples/Multiple-flt.riscv.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32F_FADD_S_RRR_F_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32D_FADD_D_RRR_F_64_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32F_FDIV_S_RRR_F_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0xc & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32D_FDIV_D_RRR_F_64_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0xd & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32F_FMUL_S_RRR_F_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x8 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32F_FSUB_S_RRR_F_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x4 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32F_FMV_S_RR_F_32_1(r3,r1) do /* MV */ { riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -#define RV32D_FMV_D_RR_F_64_1(r3,r1) do /* MV */ { riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FMUL_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FADD_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32D_FADD_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FSUB_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FDIV_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32D_FDIV_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 2 floats and return float */ -typedef float (*pifff)(float, float); - -/* C compilette prototype */ -h2_insn_t * genAddf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x31F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genMulf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x31F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genMUL_4(r, a, b, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genSubf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x31F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genSUB_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genDivf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x31F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genDIV_4(r, a, b, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - float fin0, fin1, fres; - pifff fPtrf; - int resultOK; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - resultOK = 0; - fin0 = atof (argv[1]); // Get the users values in1 & in2 (flt) - fin1 = atof (argv[2]); - - ptr = h2_malloc (1024); - fPtrf = (pifff) genAddf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple addition of 2 floating point values:\n"); - printf("%f + %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 + fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genSubf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple subraction of 2 floating point values:\n"); - printf("%f - %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 - fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genMulf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple multiplication of 2 floating point values:\n"); - printf("%f * %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 * fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genDivf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple division of 2 floating point values:\n"); - printf("%f / %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 / fin1)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Multiple-int.aarch64 b/CodeExamples/Multiple-int.aarch64 deleted file mode 100755 index fadeda4cf1d0df9f07312f9e214fc7c8e94a9cab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52288 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -// X * NPowerOf2 = X >> N (immediate shift left) -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSR_3(P0, P1, P2); - } -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (aarch64)\\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 2 ints and return int */ -typedef int (*pifii)(int, int); - -/* C compilette prototype */ -h2_insn_t * genAddf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genMulf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genMUL_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genSubf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genSUB_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genDivf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0303, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genDIV_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res, resultOK; - pifii fPtrf; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - resultOK = 0; - in0 = atoi (argv[1]); // Get the users values in1 & in2 (int) - in1 = atoi (argv[2]); - - ptr = h2_malloc (1024); - fPtrf = (pifii) genAddf (ptr); - res = fPtrf(in0, in1); - printf ("Simple addition of 2 int values:\n"); - printf("%d + %d = %d\n", in0, in1, res); - if (res != (in0 + in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genSubf (ptr); - res = fPtrf(in0, in1); - printf ("Simple subraction of 2 int values:\n"); - printf("%d - %d = %d\n", in0, in1, res); - if (res != (in0 - in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genMulf (ptr); - res = fPtrf(in0, in1); - printf ("Simple multiplication of 2 int values:\n"); - printf("%d * %d = %d\n", in0, in1, res); - if (res != (in0 * in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genDivf (ptr); - res = fPtrf(in0, in1); - printf ("Simple division of 2 int values:\n"); - printf("%d / %d = %d\n", in0, in1, res); - if (res != (in0 / in1)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Multiple-int.power b/CodeExamples/Multiple-int.power deleted file mode 100755 index 80db09406210c6b8d25f2ba9ce64b0566da20610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78336 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 DEbbwn diff --git a/CodeExamples/Multiple-int.power.c b/CodeExamples/Multiple-int.power.c deleted file mode 100644 index 237c287..0000000 --- a/CodeExamples/Multiple-int.power.c +++ /dev/null @@ -1,1086 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (power)\\n"); - #endif - P2 = power_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 2 ints and return int */ -typedef int (*pifii)(int, int); - -/* C compilette prototype */ -h2_insn_t * genAddf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x781F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genMulf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x781F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genMUL_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genSubf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x781F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genSUB_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genDivf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x781F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genDIV_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res, resultOK; - pifii fPtrf; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - resultOK = 0; - in0 = atoi (argv[1]); // Get the users values in1 & in2 (int) - in1 = atoi (argv[2]); - - ptr = h2_malloc (1024); - fPtrf = (pifii) genAddf (ptr); - res = fPtrf(in0, in1); - printf ("Simple addition of 2 int values:\n"); - printf("%d + %d = %d\n", in0, in1, res); - if (res != (in0 + in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genSubf (ptr); - res = fPtrf(in0, in1); - printf ("Simple subraction of 2 int values:\n"); - printf("%d - %d = %d\n", in0, in1, res); - if (res != (in0 - in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genMulf (ptr); - res = fPtrf(in0, in1); - printf ("Simple multiplication of 2 int values:\n"); - printf("%d * %d = %d\n", in0, in1, res); - if (res != (in0 * in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genDivf (ptr); - res = fPtrf(in0, in1); - printf ("Simple division of 2 int values:\n"); - printf("%d / %d = %d\n", in0, in1, res); - if (res != (in0 / in1)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Multiple-int.riscv b/CodeExamples/Multiple-int.riscv deleted file mode 100755 index 34231f833910a10176eb3ed81122016c3ec4cb4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53836 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 diff --git a/CodeExamples/Multiple-int.riscv.c b/CodeExamples/Multiple-int.riscv.c deleted file mode 100644 index 7bdfe2c..0000000 --- a/CodeExamples/Multiple-int.riscv.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 2 ints and return int */ -typedef int (*pifii)(int, int); - -/* C compilette prototype */ -h2_insn_t * genAddf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF3F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genMulf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF3F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genMUL_4(r, a, b, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genSubf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF3F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genSUB_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genDivf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t b = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF3F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genDIV_4(r, a, b, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res, resultOK; - pifii fPtrf; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - resultOK = 0; - in0 = atoi (argv[1]); // Get the users values in1 & in2 (int) - in1 = atoi (argv[2]); - - ptr = h2_malloc (1024); - fPtrf = (pifii) genAddf (ptr); - res = fPtrf(in0, in1); - printf ("Simple addition of 2 int values:\n"); - printf("%d + %d = %d\n", in0, in1, res); - if (res != (in0 + in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genSubf (ptr); - res = fPtrf(in0, in1); - printf ("Simple subraction of 2 int values:\n"); - printf("%d - %d = %d\n", in0, in1, res); - if (res != (in0 - in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genMulf (ptr); - res = fPtrf(in0, in1); - printf ("Simple multiplication of 2 int values:\n"); - printf("%d * %d = %d\n", in0, in1, res); - if (res != (in0 * in1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifii) genDivf (ptr); - res = fPtrf(in0, in1); - printf ("Simple division of 2 int values:\n"); - printf("%d / %d = %d\n", in0, in1, res); - if (res != (in0 / in1)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/Demos/Newton-SquareRoot-VariablePrecision/Newton.c b/Demos/Newton-SquareRoot-VariablePrecision/Newton.c deleted file mode 100644 index d18ae26..0000000 --- a/Demos/Newton-SquareRoot-VariablePrecision/Newton.c +++ /dev/null @@ -1,925 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -void RV32I_RET__I_32_1(){ /* RET */ - riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_RET__I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_ADDI_RRI_I_32_1(int r1,int r0,int i0){ /* ADD */ - riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_ADDI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_ADD_RRR_I_32_1(int r3,int r1,int r2){ /* ADD */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_ADD_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SUB_RRR_I_32_1(int r3,int r1,int r2){ /* SUB */ - riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SUB_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_MV_RR_I_32_1(int r0,int r1){ /* MV */ - riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_MV_RR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_MV_RI_I_32_1(int r3,int i1){ /* MV */ - riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_MV_RI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32F_FMV_S_RR_F_32_1(int r3,int r1){ /* MV */ - riscv_G32(((0x10 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32F_FMV_S_RR_F_32_1\n", h2_asm_pc); -#endif -} -void RV32D_FMV_D_RR_F_64_1(int r3,int r1){ /* MV */ - riscv_G32(((0x11 & 0x7f) << 25)|((r1 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32D_FMV_D_RR_F_64_1\n", h2_asm_pc); -#endif -} -void RV32I_LB_RRI_I_8_1(int r3,int r1,int i1){ /* R */ - riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_LB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void RV32I_LH_RRI_I_16_1(int r3,int r1,int i1){ /* R */ - riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_LH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void RV32I_LW_RRI_I_32_1(int r3,int r1,int i1){ /* R */ - riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_LW_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32F_FADD_S_RRR_F_32_1(int r3,int r1,int r2){ /* ADD */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32F_FADD_S_RRR_F_32_1\n", h2_asm_pc); -#endif -} -void RV32D_FADD_D_RRR_F_64_1(int r3,int r1,int r2){ /* ADD */ - riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32D_FADD_D_RRR_F_64_1\n", h2_asm_pc); -#endif -} -void RV32I_SLLI_RRI_I_32_1(int r3,int r1,int i0){ /* SL */ - riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SLLI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SLL_RRR_I_32_1(int r3,int r1,int r2){ /* SL */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SLL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32F_FDIV_S_RRR_F_32_1(int r3,int r1,int r2){ /* DIV */ - riscv_G32(((0xc & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32F_FDIV_S_RRR_F_32_1\n", h2_asm_pc); -#endif -} -void RV32D_FDIV_D_RRR_F_64_1(int r3,int r1,int r2){ /* DIV */ - riscv_G32(((0xd & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x53 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32D_FDIV_D_RRR_F_64_1\n", h2_asm_pc); -#endif -} -void RV32I_SRLI_RRI_I_32_1(int r3,int r1,int i0){ /* SR */ - riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SRLI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SRL_RRR_I_32_1(int r3,int r1,int r2){ /* SR */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SRL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SB_RRI_I_8_1(int r1,int r2,int i1){ /* W */ - riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void RV32I_SH_RRI_I_16_1(int r1,int r2,int i1){ /* W */ - riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void RV32I_SW_RRI_I_32_1(int r1,int r2,int i1){ /* W */ - riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SW_RRI_I_32_1\n", h2_asm_pc); -#endif -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32F_FMV_S_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32D_FMV_D_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FDIV_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32D_FDIV_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32F_FADD_S_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32D_FADD_D_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -/* -*- c -*- */ - -#include -#include -#include - - -#define True 1 -#define False 0 -#define FLOAT 32 -#define DOUBLE 64 - -typedef float (*piff)(float, float, float); -typedef double (*pidd)(double, double, double); -/* Newton square root demonstration with variable precision */ -h2_insn_t * genIterate(h2_insn_t * ptr, int FloatWidth) -{ - /* Code Generation of 4 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t u = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; - h2_sValue_t val = {H2REGISTER, 'f', 1, (FloatWidth), 11, true}; - h2_sValue_t div = {H2REGISTER, 'f', 1, (FloatWidth), 12, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, (FloatWidth), 10, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, (FloatWidth), 0, true}; - h2_sValue_t tmp1 = {H2REGISTER, 'f', 1, (FloatWidth), 1, true}; - h2_sValue_t tmp2 = {H2REGISTER, 'f', 1, (FloatWidth), 2, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'f', 1, (FloatWidth), -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x31F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp1 = riscv_genDIV_4(tmp1, val, u, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp2 = riscv_genADD_3(tmp2, u, tmp1); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = riscv_genDIV_4(tmp0000, tmp2, div, immValueZero); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - /* r = (u + (#(value) / u)) / 2.0*/ - - return (h2_insn_t *) ptr; -} - -#define ABS(x) ((x < 0) ? -(x) : (x)) - -int main(int argc, char **argv) -{ - int isFloat, iterationNumber; - double af, precf, precd, value, next, diff; - piff fPtr1; - pidd fPtr2; - h2_insn_t * ptr; - char input; - if (argc < 3) - { - printf ("Newton \n"); - exit(-1); - } - iterationNumber = 0; - af = atof (argv[1]); - precd = atof (argv[2]); - precf = 1; // precd * 1.e14; - ptr = h2_malloc (1024); - isFloat = True; - printf ("Compute square root of %f\n", af); - printf ("With precision of %e (float)\n", precf); - printf ("With precision of %e (double)\n", precd); - next = 1.0; - diff = af; - - fPtr1 = (piff) genIterate (ptr, FLOAT); - do - { - if ((diff < precf) && isFloat) - { /* Code re-generation with double for better precision */ - fPtr2 = (pidd) genIterate (ptr, DOUBLE); - isFloat = False; - } - value = next; - next = (isFloat)?fPtr1(value, af, 2.0):fPtr2(value, af, 2.0); - diff = ABS(next - value); - printf("%3d %s : %.20f, %e\n", - iterationNumber++, - isFloat?"float ":"double", - next, isFloat?precf:precd); - - if(iterationNumber > 100){ - return -1; - } - } while ( diff > precd); - if(isFloat){ - return (next != sqrtf(af)) ? -1 : 0; - } - else{ - return (next != sqrt(af)) ? -1 : 0; - } -} diff --git a/Demos/Newton-SquareRoot-VariablePrecision/Newton.riscv b/Demos/Newton-SquareRoot-VariablePrecision/Newton.riscv deleted file mode 100755 index 671c4acab69894ef561e7a5042da5600c1936973..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65000 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 Xh8xA~X$ChbwtM=zb9GB3&4T{}x?h_3 diff --git a/Demos/Stencil/Stencil.aarch64 b/Demos/Stencil/Stencil.aarch64 deleted file mode 100755 index abf8305e08911bde0a495f8f6f93e6d20d69f94d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86152 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 pxy)x_=u~%x zk@3t$)W{hdf!u?04Ek&vq4-@kf?Oc<34i>+HN^FH?d>UQIK?&;QH$f+2GtJ{TY_WKHauk8hQ9Z<4PoXVt(a0H{$cNm+-F_? zS(R=ZIvv~asAC)Au5C~*pb*<&$GOteQE(gEFy`8ZZMJQIZnHio-`h4Uc@^70t-P@f z-MNVXG{x60ux$hPj_;LiP%MjW07sf_pdR~_FEb)MifL`zP;J|WF2^;z@hGC-z+jauehA zs(0oLo>*~0FMvM=JXSB&-R@coUb3tZ5(#}Hu?e1N&Q%3>qjf~xQ0K|=c8iCV6^*FX?u&Z zC6jwEpJbBU-(-Hm(T~H9esp9`<|n8P&m>lpt{VLSx6zMITMm_HG`rqaT@Oo!)PB#Msc^ z=duU0a}%ofKHg;O#&`$M2K1-v$7$*vquuE>=w(II>Bn`pegH2`KMd?YPd~P?COR)L ze5`i#gF5dC{n#^ue)OKNAGV!hJ`;N|_ zz|j%l**>J?d>!dPU&vk(3j-eubi}}&)RAK5`(C+Vccrx0$HbqaA^PEOc4xO(jyP+dZPv!<#JL=Qj99|%h81K-t2^X^V z4>)>a;~N8>?Muj?niwl3hu3M#gmM+ehfsg6+U@CN;P=FssuLgYNUc#P&;6$OPwpOA zwjWtMMMug)$NOC!vES7Y1&6I8W$eMoIZ8(kytj_r3=g8+>2>POW1fjTcahPNlpJ13 zz{ykCygJqE>IiuXYRQ%BoX`<)8y)F$b>tyiN1)s2NPJR9E|@__e)9@CV%MwhPA*4B zsKbum<>(0ak5>oK5&Ic|IC##}k+`cP)N>Q(4!77jz38%lts`U75#^iMgY~jbCmkJG zo~|QzYMr{*r|C#@Y&spGUR!%G;HK$_fjg-q@1-B3*ae-_8a}#tir&&m{g^3F;me+0 zKLXdK=!g9b-+8f?Z_RnJ)^DL>1btABTRI_K8L!BWEMToNFMQbOgYp#0e=DA|^}x>A zY29O22TUv#T`gJR3=%q?BabCs$E&Z4j0q=ea=c)T*?*k!UB_N=@(d{3@VuEbpzG3N ztmq4lZUDpfA7$t3M#UO~Te(%^Kfp1m8{{2L%y(Txbcycibn`3BKU%RNZOwzvdsfV2 z{?q308XVoY+0l)b?8*E@eL1?JJgQ5G+)zwT(SBhpP&RrZ?1cjy=|M%-^0PHP&irD;2yRFM~l6jXmnY zL}R7%zu&sd?71O5&;R#4|MPS|$zFSZ`&-}o)^}TLueJ7?!JEi0#CLeTD8uL%{XMyu z|4HU`r@o!=3ps}8wuv#k4#8Jwe8RJ|`#o2gcn9%B`oRVP^G&Xz_^$+CLM%cXLAGEpYrrk0&6h@6t$k_0G85{Ca zWNe`EiF`xfath*Ph3s2a$k?FzmNGW%xp-{&{AI+30vQ{+Y{Pc&)VpLf`ju1AuS9IP zpJIdRS5_c4U`;OKAs@T!$;Y^Aii{1aUs)u_CuD4>6nuroC-N%Lx0JD=D>615z}lfe zo;OlXU8EzdJ8m?NU8=q%Xd7b#r+aDb=6L8Nc6?%TxZO-NKH*7`ayHHlLl2D=hITVi zzcRMn{QQ+D-}ooe`IOEy=z+g~?M@NzUys=E{-yerqP&5}m2aqi<#ai|KN)>NVHY$u z!Qa1n$`I=?M&YT5`~EeL%f1eM%Zlz@hVlLN`=yV7p6FX%5#=LO(6>}RqWYG~N2VD1 zmKXPtCn1MGS6zhek9TTwQ$s!yHHPxg(BpRd8Q{(%HZJEJG z67?<1WBQge!AC!Q!q~S|eM!}~Jo6v6Vd_V!zNHm9QsZ@jw{64Z1A}>Dj}oImMD|=Ez4!!a#=**ax<6tM)WP0MfiquyYvmv5bej5Sl`Gi=VgccmgTZ6(B`l73#W%uZMEilfgMTviEg@G!`$75|+AVaV`j$yt zZ-()^pe?+HqGK8QmF2u&Ip~2c>B}R=CaioN*3FS}YKrF@s&9!p8`}>~`_g>lZs;U- zT%sWC8;Qmxx)S)tBSzm4drQQ;cdd=}jhn$oMBgeSjkg~YAV=PQ^rVXR!x&|N1pC^H zu?f%oOAMq<65o<65C`-J5k&j?bo8G?$F76{!$Va*wBXsY)DeNOT+(!)KcR6Wt zY(mIuNViEJp|Oc+@Db79BYS-xW%IEKTcz}oD)IgWzPXR=4*SS>loL-rM^D2~=3;+m z`o42E{KPdKV-wO(kbiJm8v0o@W{7zplyer}`lx;u_mezZH?SCxh~MC>yW<0oCQesUCiMEJ=f(!1DuMXaAl8y@u7y8B&) z&^`9(<$fZ{8vs4wCp6DPeqtEEYZNx2#wvzfkp1JLJ&Aq~d7IYxbZx>qqsne$A8S{c z^byb!?MPvikId+NuSfX^^(`^RjWUFf%z%$zPM3V7qmtW5qFC*Q3<7z+2;B!3g?(fU z_YuSRU8VGql|oiSUCKwWhQd_@If?!r+3Nc!oBPNk%15>e9|7OoM^1%(WNZQ-dF2#* z~jQUBgQBob9`$u*qDa6``2GX zaT@&mwZ|ydV-9Ahmwd1|a*X19`In4Qz&>bQ~4aEnPIRO4de4zOgiVw5GYbb2X!($Y^usMA(?`uZKhF58Q zQ(ggs6R{VQq?$N0CXuH(E3E;h5ErfCQMt7b*GDA zL-EHgzlwSXx>_P^on5ZY%_vo46U9+u6EY@zU&aJiT6k=t2YZiT9z%>ZrLdK3XM&;AgkGn#kgfxWK3w`>(4ev$|);eOu(MOd|ef2 z8~c`=Zn)jNSerSBI2bcF(K9pLW+ob&*qs)?&FoliXfwq(MKNur3wG&`T(^D-d_=UF z|0Hy7haPy}vMWuFO;F!beP2Xv!Se0_&=Wp^d3o*=_@)qTRKIH$))fi62#rmwCHutK z#BSt^)3+SKW#5YRMUlSYOp@&;=!tf7R&2ZJSv<^rMScetKw05-6Z6^BZk|})O}r-Z zkxs}Vkmrxk{ZUPun-=ns>5)G2bLk^bNgwG|K0@C$%!ZGsZ;c=;l+Ar)K>3LJ)=2t@ z|KdK9NDf)*fEWN2Wt3gL&z&r#XCGAj$CT9`FSlK8taQvxtT7VqFF4p4R`-dc${Vogd2O zdv{G+fp-dL_q!*s4sihgYApulQR%x4YIA8#p<0J@mcBQ~w;a^}R_zF_!Am7RT(8;d6eCg~ z6WTNN%!fi2z4$(w=EL~!%s^Iy18Kwg;Dgqe(mq;LN0K#_!{`1wP=DyMzvn9cK195$ z^^rrnmFQZd-o04(NUwDq+7IXiYj0D*+u)zbM|JG4 zxJ7)s8%)ER+_{)WFgi`^ntf?`U*Y<(FZ%~qq3>rc}n=l;BGvJ zJ<@li0a{Qhze%IA}kALACJNVdjom?ByI{@DRZ|BZS-{|>r-?*L2{T9sq zMEXYHg(%Z;(9? z<=OeVNwUjxSxZEpM%vd?S0@@~akPgQqBd+|h+Pq?lP`vl6Oy#!)>LY5oyiAR)A2p->C8|xF- zK?Z@YTO;(o{xQ*BkWcXTVx^Ep4)+Z)ZZ}vdd?Fuw2%ix9-17DU<#7Kvf%^0I;@a5u zqQ}l=`$Tw-dO^ofubu0qcYyptj5+jyw{sqYUr^c9UigJy4EEr;^wDa*)@pl%jCTDf z(l^K_Xnd6VOJ`9I^`rQ^2k23MihQHb1^ez0d!$o)F$Q&{b-wg{Gs%$pzhh0ezew%J zI6R|%0JR~f5hJJ%GuW6e_Lpo%ojvn9mY@%#_CprmYpmqHDfT^2;qN~54F{FW_jy2U zqIV6l5888q>f6_WZ`b`;Q;t2+IiI`5cOAxWI=D_A2QTPz{S>^Yz03R1XFG@f9Pvr} zJe-675kCRck$+Qxc8d0NIMYRaN~{+`J$YXf<&$iP7b=s+wMjnIhog8#b#`K&X-LmN zyE(s8?aSG>8#;nc`c8p&(CV|Tl>K!l*Dvku(FY#rx2`xJD2L)P?>m9!*=z>=i2ZKK zPS4?c4*G6``rF31uoZP2+@3y6?LjZro$=qp*(rR0`i(c^JNlu#jP88o>@4;PCE-L!V8YX|1HRz}1F=iiHXFaq|$_dP** z)Q=pAd+JB__bfm^348Gx`;Zv>2vGSXE69S&p;GYiEWWuSUf$~xz8XCSay98W@3sh= zUyt7+A(_xVi##rTA2Pu=DrvW?@rmht-TGihI{J~V$LzqXG^?f|D&HBgRqwQSd?56!0gI(|qd{f`MB&WL<>xrmO znF+oI?^p4mO~i)>(l7M)TnAaHdHNY0L%TDC9d)eacBIB2`l!sV72!T5%I7hnN5%*b zp2Hp~PF3m~Y>;(L1PXOa)ROJ%|b&LUor54;E3m(s6% z0daA#3;y9+$lFkQPda-_wxJl4;BDxMl5W~t)A-KC`zY{N-nKph`NK9N-@U{>6@32* z_mmAk z7NR}HZ@NJS1=H!fdc=$qE4%x^8*fW{Wn0=Mc)ghKywBJ6?8LlRr0+Pk2;Z@QpI+>L z(FgkC9c)pkO{MRCjJ}fuT*&wN_nnQ9N1$tGge^EX3*X5BUG6(i zkxbB*!k@-LX0#6wwFQGeC*Rp|Y&`JjJ&3=9VULIRP*#NR5HIlS{+>m#zN2F=D(IEI zQ{uj3Th)C|UmDTxeEWC70~1h2Kjs;Ce?|5`Po)o&9%vq)!NZ^q9O*Z=L1$+0 z5y1W`Y`rr=W`R03mwcPn2ZsH}$=kS)|DcQr|3Mk#Kcm1eja!UC{&zc6yBhx;?F+<_ zL04us#a3#!GLzsldEga18pkjC@y%{RU#eWiWgh8E@|%)G{Zh;+h;fX_@AO|Kemt4n zpL#uWJIJ5J7zWwQJmE)g!;iq@$W*eETaS@H<>P&zA2GjRx>y(8+X(rCFVg9`*-N?4 z54pf6?1prAF<%-@zJ#`K(6g$WtuHa?<>hhfZxsHN26^@3+tNOiL;ghV0<}dpJND4R z`c$Jo(YK5N@DR}!b*$>{M_izF+{EL1F2N(&QFME>2Qs1dg!V&Y0V6;7&9-XcTVzMv zw>~5}<#XR6yH)RVg9GGS;0tY#8sDIpa27E^wMoPS@kp{Ujf6cQR`z=)Vca2;%kd8M zcgZLEz&nqfkD%^rVc)QG>O&~Iw!*)5f7RJd@js~Bhm%G@R@U*|y=V*i5m(SwJ(dFA z2LF`K_kB|SMsld7@ALUM?bMDyF#Q6RGt`4U@WkmQH${;@*hkWE`W5)?U8;?3s z-!^9gDCd9&$gk*p4`+O+J*yqcfM1DrU zKVuj-q&}bIA=Kxawi@!D0YAg<2!r?c_JsXx6v~hGwI?B)0OAf?UuNJ3zX^xmBBA~t z?a$5qY$D02pu-BCQ#(es&D*dXJN&HWSke{P#~Zk0?{$0)J@o^pbx`>cZ5j9@pCjH# zUL?oR*okWd-)D>btG5#M?-I7H{H*Y|@UyQwyVFrlaJHTLfRFXolb;pxKA@d^Y?^&I zt$^ZWs~kVEbDyFySK((x9YdZGkkNG5%Ia?7Lw#G)M`g|yenvcS-vOQR}wE> z!oSSmCs(#%DjuJiPqu?LAK#z^7TJg21D~c@x1$Z)!rQWf=@@%O+@&!V-Y0wnJ_g>1 z_j9LYTee%+&6l-hwa^L0`2gblU>E#s{bGY&(4I{Yel`Yt_96!Mp)B&VvA9=b^z^M# zq@P{W5da?%?b!+F4zi^AnNf40gIfVHb}Qenz7FfjL|+l_StvKczrYvqX}cCa0{@~mm;8%lIn;}NL&5VM)c++r z96;UA$F^r{Pr%PMIJ;?I(4a^9*{{jZW^g|nL4J0VeK=zw`PmLR7Nh)3&Bf2`7}7_g zeC(-VTO<8Uj>k~Bo+v*fKBzs@v8Ntl_b0t!Kl>2tXXxEGfOy9OOD^d*Nf>w!cpTjK z=-tbV{;~2s^0_|n#K$lnM?0i`lLTc``$qF$^xGtf_T6ZNE;Z2a_vCia*aO8Ok~Q}= zIVMc~>0bCHqqznAE(qa(oA!fL`@5Y$+d^#_`5vudIR{@0>;zr(Mc+sN=acRBVH$TK{>&K9 zd>{5f?{4oSp7%D2vDf!zmjGYyTvk|hjOzV9${Ijf{jL-qrzv*EnkXyjsW!lkbUsY*8zT=H;6^&P8Q?}bV-mohH~c1vkRcT6Tl}K;6^$ZJ_*w| z(m9X-zQh1G(wSs{8|nP}`S|pG2Dp(FhDUjdXklxRK6pK8{c4Rs-Bf z=XwL&Nay2^;?sH105{UvVSpRyj7k81_QNoJBb^5ga3h`h3E%_&8K2Ix2Dp(J^{SU05{T^Xn-5( zbiW^;euDvSq*Imv{=eT7zm>Ev@1=2<$=}&J0N6zQRucW+ob8;t^0sBRrx@Fup315( zZ2$LTAKs>AExpaO_J>Tft=Zw+b3tdFkFku(>G)6n8TyRejekqX0}p8pW%lo zmJZ7I&c-tf9>jmHlXW`xK3KJgB@fgDgVpTGpH^uL%=Tx&%Ncz{!6H*?<1QU^aPQYN z+YiChm1Z{Lhb+Z*>NWq9KYY#mI%9KEm%sk=&e+1O3hv{eF{%y?EIUr!8xTmgQhsl{-zW@i*zLI^E># z{!lkP{AWF@fPR1KsFqbZsOts%cc&)qT0_4%MYySHta^WvbGY>z&OHObCAqzOjdQ9A zz*z+amSAI9MTu%Nx?tq zeFgN=Z*dM=L3>du+x#8m*Lw0h#y*d+Bj^eBdhtxM#`QF5V_-pUV_*T3dfLfYNKXuU zDrL+T(9;T@Vrg7YH5#+M23RgjtsDnE}%VeJo9SJlarFi<~+s5aXppjHrwlL z9LHnOlfb*xfXBF=h~9BYk8s#)>m?4$nF>AK!P0HdGK+1IW^c@eu1eEh8t48(-&}g~ zz&JPRT6*+>al0UI7;WeAVwTg0JWs#wc#?ELa-Ya-jZK5WYSPtPR^lV8@@-vfw0#n+ z9=xga*ry)XvEjzDW9QeF9J{dnS6u(3_h+Gh(g*3D^iI0_3^qXeAI@XL!=!(!&_CHj zHn)N7$_Jp=Wo8E2reo0g!@BP5{#4H{7=qr{Gx59t_I@5PqR*@t$Aa$9=%Wjcnijo0 z5p|n{JnZEDak+Rl5p`s!<2zNR9DfoU;dph@lSGqfO=MY(X@5rDz{jU}mJ3+Wq%{tF zA?ikT;`PfT+ZJ`Zu>BVi^J}tef6LW2Ac>RzPzYhTK zAK-^s^8O*ndH3?{oCjfR7VvvJ`0RSs^JMO;8=l*glw`4sBizBUtzo-{QVKSA-*V2H2#I{PaS&) zyq}T&ig&4dSYSctt;h?#j+}v%Vj}5O`SE$+Zos#)lkw~wofVWKMxN2L9}ehQ50?S9 z3(tgoi1?tMy&EK2LY{&ad-y!c=4I}>4(kg{$G(RAL`MT3xq<6C^Kn0f@@}^~r*aru z*y*7%V4tLe@4+@c&0)i&gHKBrc4FR-%l(^>Gs%1r=?U>|((=o4Q2&RqANVkA=V6lV z2FQFBXc6ur*v1Et^BLecwOwoe{7mq`6TlJWT-JCuWd3Om<_+;&$(>~W*)ze>7q_F3V|O!=@qz?lGZUk~!72CW#GmnptFbJzS4u zJM`~JVm}M&BmSU%zfZ}H=wF69Kk@XmPQnX7{=Y+6?;zE7!3H^Pt#dre>BaRs=UL|& z{W6rNb@rIp&wBNeYj)nvHrI|>cB=#R{v3HHn%U-GqMm2K6Vam>d6sB~@@7B$9PR^) zoZX>!M(_;&_-|U0y(EHDyFh$i*#0laxE|Lp>{K>IyprxIX8Z*79X9qe*ww>Y>aI1U z`+!U9d>?SEZP><^-AOuaJPJP{yE%hrEU>V%3byqQbVGRv|1IL%aQ`~)d$Y98ck=LC z!FVogX;J4dqVP`A{cI!7Rh^FmMrAvH6sK&*qRwKJjWrq9Ogzmtm!Qr52Z8bUy~X?)pYn&KTFC&hxMVvQx5yUBC%I|M2V0n-C|^&TTG4nvLfquXkXt{xz57 zoYBWXC!-#w7*P7$?2bC*J74MS-f7C_b{kmY>?V7C3h`k;#D|Ah6K&YKvR8_27qcb{=bEJ{w_yJ_ip&~BsTx0UfopikVEV4(E?X*Sib7i z9pLj0$J66(M>}g`lfLU_+Q2)|%^j#4(U`Q|_EIS`cPwJ2fuBG&56stJdIcb}6tR}_5g+b+vg@aK47jlUm$FTSba80RBrc-P4RuZJ{*Bi< zHnp@iw|PBn>hTouV5(zrO+%Bn*5PTc^*ZXkK5uJHTSK!iRpCvZ>EV}?XUwW~TWo3XFdG_7o0Z0>qD|dB(2{1s@7(@uW4%cR&3fN%3U?N z_F8aSJlRt`xmNt~I)%zFDJ#1a4np{AuP^<}@Gq@`A^I!6aw+6l2!HMJzYKrH^_P?( zM8B-!k{Al%-*8Fnu!>DJ_1>zQOh*cNj+!<{Q-jaznA`xHZED}-!xgd?6|Zf>^M)qJf(lr#IO@e{#dt$qnk<)Koiva`=QBAqcb^%z=MO z)j!>nmmBZ(sQVOopP>hXxC|YX$AN#6vN69c>OL*%K3(2tEQ(Lh9)+Kw@PqO3sca|y zH`O%wkg!$tn;b1Qt$we=+uGXPI^E&l*xcS!>)7CROquMT3Jc)jM%azx7K8w(8Kx$| z>=q(|W7VwG$+a+~)LByO2BoEq361tw9UBaOLH7>eL8)K6A{e|2=`N&)kTw+r zg8`&ppc9af#&gvi@PTwX^zt*LzgPl!Tad0oex!G=3kLB%&8FW7`bZaiH5mLY(zNx# zV0IE?E{I>zN04W^~{8OHz3a`ZOIBY(mm+mnwee2CrWS%_V zR-}&t2cqH!(Y_o1KLPAff|S^298Nl7aqTnh*UI;p_v&j?-+J?J{XED(UlesB|4ApTSeB-y1U{koJ!-@apfV~0OS@=bmKTeXEB(h~;x=Ui{5{-L6 z;|}=PJwi^RjxNd`kGImeG){xY$!V}%GOm!EE}f61$TkLb2*9^bQ}8OW2TX^jADQOb zQ?PgH;(b&0UwPn)gOkhd&A%`2{z->&%PmVCrmsh^lC)HqDI;37pw)6M>I8oTt>dP{ zQ;uBex_`o<%ggs%v3Ig-U;h5QvICP2=HBbLZ{iZm(($Hy;u3Qr`(vQ>v(jMjGePSk z)8V2cg=KrD@13?}U%~#V2c{gn^4=@%o9wzj|4^RkYY}8PM`TBz5I>dh8^jUtbJTP= z|43fxo=JOi%l0|;PjnraaPacdd&l3Gq222!AF2 zTe@G{XIl62OD^GeWG@sOo7M({nXo-Nh>snBZLCI|61omp$`60-$W3MY*6qJx`JS)t zy|MhjR}NlZesA@CYb{IH=u5TKH{Vh|5t8pJ(0K-QK0;hgyAn4g_LF1E4}Vub@*TZw z&t3Z7Z|mjz?$q~xOJ9264*lS6{odR4`@X5W?%$;!3Yzq+6cCMaHAXbYfTu@y1%p!> za8qi(=i2ha4_S{qXkE7FsCDlH)_q5;`wv^o4;-={yx+R`-utZg-D|!7p!LuJtG;zi z9FkmKO`v(#d$3EALAi({ReMagLB2eWl-k*;H{U{Ag2xAe``G)?GvSulR~=40l2W!O zd9Sr{zhz&N>!5zXTza2&ugSFG<(EoceWm2}*JO|bE}`v9+HW~vKB(Vox=*9L6fZvj z&2=9@-ndpYO9{z!uZhzxC)(>@eyQxOH(z_@Rf?e8uk#TnK0>~L$S30E0nG!N*uq$RxYm)LxH{vdCwy6QK9Ff+TrXYS!H`h?j7OUm$^UVfc;>) z=|)t;&=gQ9jO6hPj5d1XYPQVX^pp4DH^#_1I2lx(xt9Fm-@1pvblSbEu zOA>9F192uBeGy|B2C{#<{F?;+CV{_6;D1a4t1_LuY==x`_k#USa+D_1$5I3yy+6}Y z`?-^+WBHk}{`69Ql_T$|dqu}Mk+6^C^YQXtJy&sYtI5fq4E{OTOcyhBagQdK9|4QF zM-#-4b@DlNFX{MLB#hqw=@=sthOz#LgPKn|`ZEN-=<4!goxGsUQ|A1Cn|vnq@MWc(l=}Yv zJ&msC5|`^*$CM>i*H3lKoKZBZNa>CGH^KyjMx7Z>p0zrffV?L=HnAd{l?6m1isv80 zyyHJ#&hyWNd5hnT*z%=>i78kUE!v>emgxb7&Q%vDcQ1(5-oWG(K>;X zXSMB;bbX9YW3$&%LSoa$Ww%oD4o>FWk&hvFzCYm&~lw5Y)_XoAu{_iF!@q)w8tGU8eaoL}SuS-$xcxrj=eF z^%PuN#`Bsb&qdzMq<>Dv`UsZtCLSdH%usz6BR)vv85l z(vt~lCrCyguv5Q@tMp_#+dBxj2*gwOb0D4Z)&k&e!hD1S>1=<3fSAT(smD2x&i3En zlsu7mv;J2yX(;6t6lwiL@^%~$>tM!lAed7A1YGM-_78DmPRXMu!&&91buvqRiBqJr zeLNmyUWLfVMW^kKI zHk6)BXZuS8yq_=w97t#T`viO(r_@0Xq_drjKAmgQo(f^4C*MgGzl>krPnQmU`50Z2 z&7>#)iZ00n(z%fBCH#_vV_(iMJL&QUe)%K1+`un?PM4eb$mX4{2C>h`VEvg z^xq<}{0S$mJz0xpRXaq6k+i{EPmf34fXV`sA4y(cEz`CnXArOi|JUK)8X!VDlJ)T< z271CzEM?BH6E}xLbQW@Esz%sK8vI32ZF$IbuF*+rQL!1y} z6+kiZYz{5@nRe(nu=H;rtLB(W*WbYZt@t-{wjJ{crmePYCX7jGzs6lR{{I#KmKzC{ z$6;r2{|^3>>IjxUn($I|$B0s-z}!vH$r-=Lbrvd?fq!OAeirBC6roaU@_*niMW`4o2zDN@KjJ^5 zhF~{jIsq$z$QI#0bG&4LI!$zZ3y32cn6@s1MAHP6TKtc6O0+C(mFZ3>Xtn9vIIl6? z1*B|6gBWC&okl72ugy!Bo_-3#Pu7m2j;nz15TrmV5}vM&K$|{78>#8`9Q$N@7BVtz zgoY~{K{7`}l=;kNTZmg&;V7otueHs$U1O`rg8JkW^vo<-n$3nMmTPPpo+PCUMBG+n z&9gx(GA9Rsoh%f{Gk_FjNRb&hWy+9x1*0NtnpTlT2x+;vFUEs(L~dTX{c4Vpk%gib z;N>ziL{l;`Vzl5%7BSLT1gu zaPg#k=XMPW-B&txCZw49-P^HTW=v-(Shp3iMPnC?_1RTPkrfVc8X^u!MKPm;nUFn5 zX3Ua7u1OM+#V9q2loSC2l2vIn`3kU+5;i$$2S%d|aTdmkHcX)ki!z?1To4TxahY}{ z7ZJiS*;r~=0X8FFBpnzYiAmMcP=8qBMI>X7BN@1~q7zbGrVYv&X(i2$z+=*^5S-BL zNTEGgt3h$u0J0Gp>GQG(9U>>!VYK~G1K# z561j$HLYz$Yw0;uVN&l?dZCt=n}TXVjL&Bi+*MZ`fMAp`p#s zP>@Q!O?7mu%5C=n2RB=avAU%_jEPf6f@u3TD<Kf_|hPTb z1&fHyriqqW{8qE1@f67NUQfDevZas;a#-^8T8E@MA)4wepjaG|>UCd2HEE7T&$DPr zLXGtPrnAN`6{j>K_{Rp)o)TCg_m{$YUwg6CZG+F#)L!dl4E7KIP}U0nsP&RVgk-9E zH~KRSLe(=g@T70nEK~H63oM%ME21k0T`l03MHcjBgv(wYTTT^4hj5a&g2U_lNv743$%RYNovSQ zpDAI6aHE8&qFju_aDRcQJ%zK1X3s9J4_|ux?F{3Aj*_(wJepfHGZbFj4gO}sjjyJ) zg*7$%>K*(Gv^Z0#%8Pnq?{^*xf@!x zioAXgR&u!;YU$2hSF@?1X&WnVs+&8}?;4mVU(8rox5?XD?=8e4+CszwXvNp&2U2Tu zJBaz}K?|!4frX?H3*~&xxbZcEV2!7-P%iClZUwNd$zQk$Yk8ZlBg=27X)5$?^?JCB zr~=G~rI*ZKBL#+9gevOUSi=S8zSY~>%zSRb^xqm57~}_Nt=I1%C>Mv2uarGkC@%x# zYirtSr1nAuM5wX0iMdOgo14&_a8jgf*-E*+%|4VwZCx0)b=Fn95+P*@D?)C9P;OPH zaGn}&a6)slXBpeLkV5A{pHP##t)@Pl4=WReAysi3l5B;a*AO!#2>E`XOyWJ1- zfjY3nw6N8SrO*i8ar{j-fx>jIzC_c3^+*FEBclJh4ebq0+%QC=mB<=aRk-kIOM|~* zLj$aH+jSco5CnZJ#@#tRW1}bogdw`dLPXij)4Zvr$-C82+uV*NmZ4ks;-==BHh7GB z4rk{YfgQl z>)X;|Y`NTS3cYSbU3VQ^n$@({!|uXBa&rQ1`5%u*!r1DrVy%gay(=rHbYXR@eDdNwnj0vS3m$#4<#TvnIA?}mx_kQ>eQtg{)u15 zNScZaeZ!@;>AVIm?DGvsY^vhV_0f04kN`iF~ZgOcrjtpI2s)qs}&dF zGq(r46fTgUGMSp#j0elB#b z(D4SU)+ZRi=nW?^wT>YYZe{W2|1n#^)VhI4{1m3vA4I}anOdh13AbS*Kc^AIuXUEj zPR50&vt71$`1a7c4J;*Scg`-p^(X3u4o8bSP8M+AE{E*v9BaSlDS+9mR#&WC0rVRWan z@v%S-r;&=-L+3-k@!%6}D5d)`}MKk+282uoP17htz1918lPx*yIW+Vy3qm#>@ zr!zIaB++4Mbc|pNqV)a)FcgoDz>l@7d{BvpKRW?j@uT7qaY4tm_%~q=TfwtAlre!H z>n{QxYyV4-FCIUNj*457yrgdrt$$GPsswbD91cdsIaROqeC9z>VQf7vsa^{HsC;y@ zgtJ9X4&iI*ai!=)`@1T4)t?1E&xDhLJEHtr!DmFlX--8$d{A(jil9T_k74~${&g77 zsFR`KW{%C+KT3F}oZ7Kl;w8t&;3bYkOP3J|n7@o)y<#HU)%C#Wbov2k?) zrxObokZ-nPbqYNbvM#SuX`A|EELo zbJAKO0P?&eLAi>)8Uavn#j%-{<XU!cX%xSYn+VktpDBPAuZI zAOU>2q?7qoC&%aC+~DfQ1o({vH=!LI7WjvFF2?SZbXv{}_(=&b1;Y*&+Yi|b{LDE0 zkcSeK`?#cECjDr+r2p>;@LvFYgn_<_t7jw~XMy08e@_NlF1%C_KT~A9mE_sS3jY&< zACM1dO;RT672S_Y0v*zq<0FC3zv)4qED2{00q5V?0iG}6Z66ExXWVWWqs2=^=lGC- z{}#A(j3s_dvF&v!@Z<4c#p#H=#`F3F@XZO}wEl_s$sFP2WS*16?w0U?gttll@00L* zmI!?QT^jN{l7RlR5`WiNfzQ8X1pX@t@ZV1Wx5D0t&y&T14*%8|+7@k3BXMzA3gn{RXEWi~s!u@S{Y> z@ScKOe*6>1PiOgaocx}DuZXMT1c(2s_Cn$Rp5t@Wh|^n=POY@VYWehi30HA@hlKwM z@`z`LizU8O_A3;f&n3KC#<5+J4kqTgJU@u)KhXDg@#s4MC%v<5C#SFr_jD9X{AfR& zFY#6Xkbi#$d?$zVtP!U*62JNiCx@Sf{n4=jaMJrnl24^~`lgTgx#v?S$2%(RWSfGo z5^(;lB{1%i@EMYRKF`J2y%N5DoxndT;XmMTd1FYP0-WqBy1rwvkY=O-PhFl!K<8`% z_@^A6&OW-+$w~0rgn*<0*;$Cw28(-OcJaCkZkxJ9}An@*HlA>sGPcHuPV z3Ma!%d48>N_JFS!XlD7Co{F3X;A8&H%!A1t_buL1bXSv1B zEKH4MV^bFF-Qk{H#3zO@*VBSU_-^;AHRaXSH@X*JU*)Q$37Yp!wE`8_qhIwJ`KF7^QeE|lf- zY-%y$NY!$KaMN}r#)k$1YvG&Rxtk*-TkmaaA(3HL$Cwe0g{e_F<hpuHiZenWotCrH;06iI9jP$6Cq~ zk_IEIQ31iI-Wz~r$b~@Yo*|5ZTPb*viucDT-tDel;R;2B8owXA3}G(3A<|*sB$y00 z3MS;LS8ctDslBv}2zA^TBaEyL;);-Nh{)`%vl*8|sCKN#zim@n%?6}xts>p1u3+t6 ztfVO7>$6HqD++0{x(MqBiZ<5xH?pGIZ9ZfcXY?mi&~qxmlt_A%7{(#;GsK_LqvIzLtTR~)?r}cyS^E;a4O;j2x2e< zhBj=|CNvCS*1Ms-9{Ff?7I1OPCr#C(4I5hFH@^3Xc zaff{bWd0}loxq_>_5P{o(E3Jf$Rns_xZ%P%W1c_9!mibhbl+h30~DTrCacC%&+FFPRjiBF_ZC7 z?-dI6OCF4oSLOXuR;FOU(Z(wa3Cw#GqD-UZPgqe!aLnT}|CA9T<0K?B qN2u&a#br`Yl!$qT{zanv8xqu?BjH5k -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_I_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SDIV_RRR_I_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -// X * NPowerOf2 = X >> N (immediate shift left) -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSR_3(P0, P1, P2); - } -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (aarch64)\\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SDIV_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include -#include -#include -#include "ReadPgmImage.h" - -typedef int (*pifc)(int[], int, int, int); - - -void printImage(imgStruct_t *img, char *imageName) -{ - printf ("ImageName & size: %s %dx%d\n", imageName, img->height, img->width); - for(int line = 0 ; line < img->height ; line++) - { - for(int column = 0 ; column < img->width ; column++) - { - printf("%03d ", img->pixelsArray[line*img->width+column]); - } - printf("\n"); - } - printf("\n"); -} - -int imgSum (imgStruct_t *img) -{ - int line, column, sum; - sum = 0; - for(int line = 0 ; line < img->height ; line++) - { - for(int column = 0 ; column < img->width; column++) - { - sum += img->pixelsArray[line*img->width+column]; - } - } - return (0 == sum)?1:sum; -} - -#if 0 -unsigned char clamp(int value) -{ - return (unsigned char)(0 > value)?0:(255 < value)?255:value; -} -#else -#define clamp(value) ((unsigned char)(0 > value)?0:(255 < value)?255:value) -#endif - -pifc genKernel1x1(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 2, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF030F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, line, imgWidth); - tmp0001 = aarch64_genADD_3(tmp0001, tmp0000, column); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = aarch64_genMUL_3(tmp0002, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = aarch64_genADD_3(tmp0003, In, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = aarch64_genR_3(tmp0004, tmp0003, immValueZero); - sum = aarch64_genMUL_3(sum, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); - if (!sum.dontFree) h2_freeReg(tmp0004.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0005 = aarch64_genDIV_3(tmp0005, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0005, immValueZero); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -pifc genKernel3x3(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 19 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 2, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 13, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF3F0F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - njp1 = aarch64_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njm1 = aarch64_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = aarch64_genADD_3(tmp0000, stride, njm1); - tmp0001 = aarch64_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = aarch64_genADD_3(tmp0002, In, tmp0001); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = aarch64_genR_3(tmp0003, tmp0002, immValueZero); - sum = aarch64_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); - if (!sum.dontFree) h2_freeReg(tmp0003.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0004 = aarch64_genADD_3(tmp0004, stride, column); - tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = aarch64_genADD_3(tmp0006, In, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = aarch64_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = aarch64_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1]))}); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0008); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0009 = aarch64_genADD_3(tmp0009, stride, njp1); - tmp0010 = aarch64_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = aarch64_genADD_3(tmp0011, In, tmp0010); - if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); - tmp0012 = aarch64_genR_3(tmp0012, tmp0011, immValueZero); - tmp0013 = aarch64_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2]))}); - if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0013); - if (!sum.dontFree) h2_freeReg(tmp0013.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genMV_3(ni, line, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0015 = aarch64_genADD_3(tmp0015, stride, njm1); - tmp0016 = aarch64_genMUL_3(tmp0016, tmp0015, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); - tmp0017 = aarch64_genADD_3(tmp0017, In, tmp0016); - if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); - tmp0018 = aarch64_genR_3(tmp0018, tmp0017, immValueZero); - tmp0019 = aarch64_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+0]))}); - if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0019); - if (!sum.dontFree) h2_freeReg(tmp0019.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0020 = aarch64_genADD_3(tmp0020, stride, column); - tmp0021 = aarch64_genMUL_3(tmp0021, tmp0020, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); - tmp0022 = aarch64_genADD_3(tmp0022, In, tmp0021); - if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); - tmp0023 = aarch64_genR_3(tmp0023, tmp0022, immValueZero); - tmp0024 = aarch64_genMUL_3(tmp0024, tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+1]))}); - if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0024); - if (!sum.dontFree) h2_freeReg(tmp0024.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0025 = aarch64_genADD_3(tmp0025, stride, njp1); - tmp0026 = aarch64_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = aarch64_genADD_3(tmp0027, In, tmp0026); - if (!tmp0027.dontFree) h2_freeReg(tmp0026.regNro); - tmp0028 = aarch64_genR_3(tmp0028, tmp0027, immValueZero); - tmp0029 = aarch64_genMUL_3(tmp0029, tmp0028, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+2]))}); - if (!tmp0029.dontFree) h2_freeReg(tmp0028.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0029); - if (!sum.dontFree) h2_freeReg(tmp0029.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0030 = aarch64_genADD_3(tmp0030, stride, njm1); - tmp0031 = aarch64_genMUL_3(tmp0031, tmp0030, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = aarch64_genADD_3(tmp0032, In, tmp0031); - if (!tmp0032.dontFree) h2_freeReg(tmp0031.regNro); - tmp0033 = aarch64_genR_3(tmp0033, tmp0032, immValueZero); - tmp0034 = aarch64_genMUL_3(tmp0034, tmp0033, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+0]))}); - if (!tmp0034.dontFree) h2_freeReg(tmp0033.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0034); - if (!sum.dontFree) h2_freeReg(tmp0034.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0035 = aarch64_genADD_3(tmp0035, stride, column); - tmp0036 = aarch64_genMUL_3(tmp0036, tmp0035, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = aarch64_genADD_3(tmp0037, In, tmp0036); - if (!tmp0037.dontFree) h2_freeReg(tmp0036.regNro); - tmp0038 = aarch64_genR_3(tmp0038, tmp0037, immValueZero); - tmp0039 = aarch64_genMUL_3(tmp0039, tmp0038, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+1]))}); - if (!tmp0039.dontFree) h2_freeReg(tmp0038.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0039); - if (!sum.dontFree) h2_freeReg(tmp0039.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0040 = aarch64_genADD_3(tmp0040, stride, njp1); - tmp0041 = aarch64_genMUL_3(tmp0041, tmp0040, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - tmp0042 = aarch64_genADD_3(tmp0042, In, tmp0041); - if (!tmp0042.dontFree) h2_freeReg(tmp0041.regNro); - tmp0043 = aarch64_genR_3(tmp0043, tmp0042, immValueZero); - tmp0044 = aarch64_genMUL_3(tmp0044, tmp0043, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+2]))}); - if (!tmp0044.dontFree) h2_freeReg(tmp0043.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0044); - if (!sum.dontFree) h2_freeReg(tmp0044.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0045 = aarch64_genDIV_3(tmp0045, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0045, immValueZero); - if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -pifc genKernel5x5(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 41 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 2, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t njm2 = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 13, true}; - h2_sValue_t njp2 = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0084 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0085 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0086 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0087 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0088 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0089 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0090 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0091 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0092 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0093 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0094 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0095 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0096 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0097 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0098 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0099 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0100 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0101 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0102 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0103 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0104 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0105 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0106 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0107 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0108 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0109 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0110 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0111 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0112 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0113 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0114 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0115 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0116 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0117 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0118 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0119 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0120 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0121 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0122 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0123 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0124 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0125 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0126 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFFFF0F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - njm2 = aarch64_genSUB_3(njm2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njm1 = aarch64_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njp1 = aarch64_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njp2 = aarch64_genADD_3(njp2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = aarch64_genADD_3(tmp0000, stride, njm2); - tmp0001 = aarch64_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = aarch64_genADD_3(tmp0002, In, tmp0001); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = aarch64_genR_3(tmp0003, tmp0002, immValueZero); - sum = aarch64_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+0]))}); - if (!sum.dontFree) h2_freeReg(tmp0003.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0004 = aarch64_genADD_3(tmp0004, stride, njm1); - tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = aarch64_genADD_3(tmp0006, In, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = aarch64_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = aarch64_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+1]))}); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0008); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0009 = aarch64_genADD_3(tmp0009, stride, column); - tmp0010 = aarch64_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = aarch64_genADD_3(tmp0011, In, tmp0010); - if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); - tmp0012 = aarch64_genR_3(tmp0012, tmp0011, immValueZero); - tmp0013 = aarch64_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+2]))}); - if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0013); - if (!sum.dontFree) h2_freeReg(tmp0013.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0014 = aarch64_genADD_3(tmp0014, stride, njp1); - tmp0015 = aarch64_genMUL_3(tmp0015, tmp0014, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); - tmp0016 = aarch64_genADD_3(tmp0016, In, tmp0015); - if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); - tmp0017 = aarch64_genR_3(tmp0017, tmp0016, immValueZero); - tmp0018 = aarch64_genMUL_3(tmp0018, tmp0017, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+3]))}); - if (!tmp0018.dontFree) h2_freeReg(tmp0017.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0018); - if (!sum.dontFree) h2_freeReg(tmp0018.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0019 = aarch64_genADD_3(tmp0019, stride, njp2); - tmp0020 = aarch64_genMUL_3(tmp0020, tmp0019, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); - tmp0021 = aarch64_genADD_3(tmp0021, In, tmp0020); - if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); - tmp0022 = aarch64_genR_3(tmp0022, tmp0021, immValueZero); - tmp0023 = aarch64_genMUL_3(tmp0023, tmp0022, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+4]))}); - if (!tmp0023.dontFree) h2_freeReg(tmp0022.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0023); - if (!sum.dontFree) h2_freeReg(tmp0023.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0024 = aarch64_genADD_3(tmp0024, stride, njm2); - tmp0025 = aarch64_genMUL_3(tmp0025, tmp0024, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0025.dontFree) h2_freeReg(tmp0024.regNro); - tmp0026 = aarch64_genADD_3(tmp0026, In, tmp0025); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = aarch64_genR_3(tmp0027, tmp0026, immValueZero); - tmp0028 = aarch64_genMUL_3(tmp0028, tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+0]))}); - if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0028); - if (!sum.dontFree) h2_freeReg(tmp0028.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0029 = aarch64_genADD_3(tmp0029, stride, njm1); - tmp0030 = aarch64_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); - tmp0031 = aarch64_genADD_3(tmp0031, In, tmp0030); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = aarch64_genR_3(tmp0032, tmp0031, immValueZero); - tmp0033 = aarch64_genMUL_3(tmp0033, tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+1]))}); - if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0033); - if (!sum.dontFree) h2_freeReg(tmp0033.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0034 = aarch64_genADD_3(tmp0034, stride, column); - tmp0035 = aarch64_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); - tmp0036 = aarch64_genADD_3(tmp0036, In, tmp0035); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = aarch64_genR_3(tmp0037, tmp0036, immValueZero); - tmp0038 = aarch64_genMUL_3(tmp0038, tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+2]))}); - if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0038); - if (!sum.dontFree) h2_freeReg(tmp0038.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0039 = aarch64_genADD_3(tmp0039, stride, njp1); - tmp0040 = aarch64_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); - tmp0041 = aarch64_genADD_3(tmp0041, In, tmp0040); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - tmp0042 = aarch64_genR_3(tmp0042, tmp0041, immValueZero); - tmp0043 = aarch64_genMUL_3(tmp0043, tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+3]))}); - if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0043); - if (!sum.dontFree) h2_freeReg(tmp0043.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0044 = aarch64_genADD_3(tmp0044, stride, njp2); - tmp0045 = aarch64_genMUL_3(tmp0045, tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); - tmp0046 = aarch64_genADD_3(tmp0046, In, tmp0045); - if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); - tmp0047 = aarch64_genR_3(tmp0047, tmp0046, immValueZero); - tmp0048 = aarch64_genMUL_3(tmp0048, tmp0047, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+4]))}); - if (!tmp0048.dontFree) h2_freeReg(tmp0047.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0048); - if (!sum.dontFree) h2_freeReg(tmp0048.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genMV_3(ni, line, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0050 = aarch64_genADD_3(tmp0050, stride, njm2); - tmp0051 = aarch64_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); - tmp0052 = aarch64_genADD_3(tmp0052, In, tmp0051); - if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); - tmp0053 = aarch64_genR_3(tmp0053, tmp0052, immValueZero); - tmp0054 = aarch64_genMUL_3(tmp0054, tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+0]))}); - if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0054); - if (!sum.dontFree) h2_freeReg(tmp0054.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0055 = aarch64_genADD_3(tmp0055, stride, njm1); - tmp0056 = aarch64_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); - tmp0057 = aarch64_genADD_3(tmp0057, In, tmp0056); - if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); - tmp0058 = aarch64_genR_3(tmp0058, tmp0057, immValueZero); - tmp0059 = aarch64_genMUL_3(tmp0059, tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+1]))}); - if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0059); - if (!sum.dontFree) h2_freeReg(tmp0059.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0060 = aarch64_genADD_3(tmp0060, stride, column); - tmp0061 = aarch64_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); - tmp0062 = aarch64_genADD_3(tmp0062, In, tmp0061); - if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); - tmp0063 = aarch64_genR_3(tmp0063, tmp0062, immValueZero); - tmp0064 = aarch64_genMUL_3(tmp0064, tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+2]))}); - if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0064); - if (!sum.dontFree) h2_freeReg(tmp0064.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0065 = aarch64_genADD_3(tmp0065, stride, njp1); - tmp0066 = aarch64_genMUL_3(tmp0066, tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); - tmp0067 = aarch64_genADD_3(tmp0067, In, tmp0066); - if (!tmp0067.dontFree) h2_freeReg(tmp0066.regNro); - tmp0068 = aarch64_genR_3(tmp0068, tmp0067, immValueZero); - tmp0069 = aarch64_genMUL_3(tmp0069, tmp0068, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+3]))}); - if (!tmp0069.dontFree) h2_freeReg(tmp0068.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0069); - if (!sum.dontFree) h2_freeReg(tmp0069.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0070 = aarch64_genADD_3(tmp0070, stride, njp2); - tmp0071 = aarch64_genMUL_3(tmp0071, tmp0070, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0071.dontFree) h2_freeReg(tmp0070.regNro); - tmp0072 = aarch64_genADD_3(tmp0072, In, tmp0071); - if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); - tmp0073 = aarch64_genR_3(tmp0073, tmp0072, immValueZero); - tmp0074 = aarch64_genMUL_3(tmp0074, tmp0073, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+4]))}); - if (!tmp0074.dontFree) h2_freeReg(tmp0073.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0074); - if (!sum.dontFree) h2_freeReg(tmp0074.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0075 = aarch64_genADD_3(tmp0075, stride, njm2); - tmp0076 = aarch64_genMUL_3(tmp0076, tmp0075, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0076.dontFree) h2_freeReg(tmp0075.regNro); - tmp0077 = aarch64_genADD_3(tmp0077, In, tmp0076); - if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); - tmp0078 = aarch64_genR_3(tmp0078, tmp0077, immValueZero); - tmp0079 = aarch64_genMUL_3(tmp0079, tmp0078, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+0]))}); - if (!tmp0079.dontFree) h2_freeReg(tmp0078.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0079); - if (!sum.dontFree) h2_freeReg(tmp0079.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0080 = aarch64_genADD_3(tmp0080, stride, njm1); - tmp0081 = aarch64_genMUL_3(tmp0081, tmp0080, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0081.dontFree) h2_freeReg(tmp0080.regNro); - tmp0082 = aarch64_genADD_3(tmp0082, In, tmp0081); - if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); - tmp0083 = aarch64_genR_3(tmp0083, tmp0082, immValueZero); - tmp0084 = aarch64_genMUL_3(tmp0084, tmp0083, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+1]))}); - if (!tmp0084.dontFree) h2_freeReg(tmp0083.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0084); - if (!sum.dontFree) h2_freeReg(tmp0084.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0085 = aarch64_genADD_3(tmp0085, stride, column); - tmp0086 = aarch64_genMUL_3(tmp0086, tmp0085, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0086.dontFree) h2_freeReg(tmp0085.regNro); - tmp0087 = aarch64_genADD_3(tmp0087, In, tmp0086); - if (!tmp0087.dontFree) h2_freeReg(tmp0086.regNro); - tmp0088 = aarch64_genR_3(tmp0088, tmp0087, immValueZero); - tmp0089 = aarch64_genMUL_3(tmp0089, tmp0088, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+2]))}); - if (!tmp0089.dontFree) h2_freeReg(tmp0088.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0089); - if (!sum.dontFree) h2_freeReg(tmp0089.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0090 = aarch64_genADD_3(tmp0090, stride, njp1); - tmp0091 = aarch64_genMUL_3(tmp0091, tmp0090, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0091.dontFree) h2_freeReg(tmp0090.regNro); - tmp0092 = aarch64_genADD_3(tmp0092, In, tmp0091); - if (!tmp0092.dontFree) h2_freeReg(tmp0091.regNro); - tmp0093 = aarch64_genR_3(tmp0093, tmp0092, immValueZero); - tmp0094 = aarch64_genMUL_3(tmp0094, tmp0093, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+3]))}); - if (!tmp0094.dontFree) h2_freeReg(tmp0093.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0094); - if (!sum.dontFree) h2_freeReg(tmp0094.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0095 = aarch64_genADD_3(tmp0095, stride, njp2); - tmp0096 = aarch64_genMUL_3(tmp0096, tmp0095, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0096.dontFree) h2_freeReg(tmp0095.regNro); - tmp0097 = aarch64_genADD_3(tmp0097, In, tmp0096); - if (!tmp0097.dontFree) h2_freeReg(tmp0096.regNro); - tmp0098 = aarch64_genR_3(tmp0098, tmp0097, immValueZero); - tmp0099 = aarch64_genMUL_3(tmp0099, tmp0098, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+4]))}); - if (!tmp0099.dontFree) h2_freeReg(tmp0098.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0099); - if (!sum.dontFree) h2_freeReg(tmp0099.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = aarch64_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = aarch64_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0100 = aarch64_genADD_3(tmp0100, stride, njm2); - tmp0101 = aarch64_genMUL_3(tmp0101, tmp0100, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0101.dontFree) h2_freeReg(tmp0100.regNro); - tmp0102 = aarch64_genADD_3(tmp0102, In, tmp0101); - if (!tmp0102.dontFree) h2_freeReg(tmp0101.regNro); - tmp0103 = aarch64_genR_3(tmp0103, tmp0102, immValueZero); - tmp0104 = aarch64_genMUL_3(tmp0104, tmp0103, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+0]))}); - if (!tmp0104.dontFree) h2_freeReg(tmp0103.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0104); - if (!sum.dontFree) h2_freeReg(tmp0104.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0105 = aarch64_genADD_3(tmp0105, stride, njm1); - tmp0106 = aarch64_genMUL_3(tmp0106, tmp0105, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0106.dontFree) h2_freeReg(tmp0105.regNro); - tmp0107 = aarch64_genADD_3(tmp0107, In, tmp0106); - if (!tmp0107.dontFree) h2_freeReg(tmp0106.regNro); - tmp0108 = aarch64_genR_3(tmp0108, tmp0107, immValueZero); - tmp0109 = aarch64_genMUL_3(tmp0109, tmp0108, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+1]))}); - if (!tmp0109.dontFree) h2_freeReg(tmp0108.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0109); - if (!sum.dontFree) h2_freeReg(tmp0109.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0110 = aarch64_genADD_3(tmp0110, stride, column); - tmp0111 = aarch64_genMUL_3(tmp0111, tmp0110, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0111.dontFree) h2_freeReg(tmp0110.regNro); - tmp0112 = aarch64_genADD_3(tmp0112, In, tmp0111); - if (!tmp0112.dontFree) h2_freeReg(tmp0111.regNro); - tmp0113 = aarch64_genR_3(tmp0113, tmp0112, immValueZero); - tmp0114 = aarch64_genMUL_3(tmp0114, tmp0113, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+2]))}); - if (!tmp0114.dontFree) h2_freeReg(tmp0113.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0114); - if (!sum.dontFree) h2_freeReg(tmp0114.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0115 = aarch64_genADD_3(tmp0115, stride, njp1); - tmp0116 = aarch64_genMUL_3(tmp0116, tmp0115, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0116.dontFree) h2_freeReg(tmp0115.regNro); - tmp0117 = aarch64_genADD_3(tmp0117, In, tmp0116); - if (!tmp0117.dontFree) h2_freeReg(tmp0116.regNro); - tmp0118 = aarch64_genR_3(tmp0118, tmp0117, immValueZero); - tmp0119 = aarch64_genMUL_3(tmp0119, tmp0118, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+3]))}); - if (!tmp0119.dontFree) h2_freeReg(tmp0118.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0119); - if (!sum.dontFree) h2_freeReg(tmp0119.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0120 = aarch64_genADD_3(tmp0120, stride, njp2); - tmp0121 = aarch64_genMUL_3(tmp0121, tmp0120, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0121.dontFree) h2_freeReg(tmp0120.regNro); - tmp0122 = aarch64_genADD_3(tmp0122, In, tmp0121); - if (!tmp0122.dontFree) h2_freeReg(tmp0121.regNro); - tmp0123 = aarch64_genR_3(tmp0123, tmp0122, immValueZero); - tmp0124 = aarch64_genMUL_3(tmp0124, tmp0123, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+4]))}); - if (!tmp0124.dontFree) h2_freeReg(tmp0123.regNro); - sum = aarch64_genADD_3(sum, sum, tmp0124); - if (!sum.dontFree) h2_freeReg(tmp0124.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0125 = aarch64_genDIV_3(tmp0125, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, tmp0125, immValueZero); - if (!tmp0126.dontFree) h2_freeReg(tmp0125.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -#if 0 -#endif -} - -// Compute a stencil for 1 point -int kernelStatic(imgStruct_t *In, int l, int c, imgStruct_t *Filter, int coeff) -{ - int line, column, sum = 0; - int offset = (Filter->width)/2; - - for (line = 0; line < Filter->height; line++) - { - for (column = 0; column < Filter->width; column++) - { - int ni = (l + line) - offset; - int nj = (c + column) - offset; - sum += In->pixelsArray[ni*In->width+nj] * Filter->pixelsArray[line*Filter->width+column]; - } - } - return sum / coeff; -} - - -void convolutionStatic(imgStruct_t *In, imgStruct_t *Out, imgStruct_t *Filter, int coeff) -{ - int offset = Filter->width/2; - int result; - for (int line = offset; line < In->height - offset; line++) - { - for (int column = offset; column < In->width - offset; column++) - { - result = kernelStatic(In, line, column, Filter, coeff); - Out->pixelsArray[line*Out->width+column] = clamp(result); - } - } -} - -void convolutionH4(imgStruct_t* In, imgStruct_t *Out, imgStruct_t *Filter, pifc kernelHL) -{ - int offset = Filter->width/2; - int result; - for (int line = offset; line < In->height - offset; line++) - { - for (int column = offset; column < In->width - offset; column++) - { - result = kernelHL(In->pixelsArray, line, column, In->width); - Out->pixelsArray[line*Out->width+column] = clamp(result); - } - } -} - -int compareImages(imgStruct_t *staticImg, imgStruct_t *H4Img) -{ - int errors = 0; - for(int line = 0 ; line < staticImg->height ; line++) - { - for(int column = 0 ; column < staticImg->width ; column++) - { - if((staticImg->pixelsArray[line*staticImg->width+column] - H4Img->pixelsArray[line*H4Img->width+column]) != 0) - { - if (0 == errors) - { - printf("Alert : first difference at line %i column %i\n", line, column); - } - errors++; - } - } - } - return errors; -} - -int main(int argc, char *argv[]) -{ - int error, coeff, nXperiment = 20; - imgStruct_t *In, *OutH4, *OutStatic, *Filter; - char *filterImageName, *inputImageName; - if (argc < 5) - { - printf ("./Stencil \n"); - exit(-1); - } - - inputImageName = argv[1]; - filterImageName = argv[4]; - In = readPgmImage(inputImageName); - Filter = readPgmImage(filterImageName); - coeff = imgSum (Filter); -#ifdef VERBOSE - printf ("%s: coeff %d\n", filterImageName, coeff); - printImage (Filter, "Filter"); -#endif - assert (Filter->width == Filter->height); // Only square filters - OutStatic = createImage (In->height, In->width); - OutH4 = createImage (In->height, In->width); -#ifdef VERBOSE - printf ("after init\n"); - printImage(In, "In"); -#endif - ticks_t timeStatic = h2_getticks(); // Static convolution - for (int i = 0; i < nXperiment; i++) - { - convolutionStatic(In, OutStatic, Filter, coeff); - } - timeStatic = h2_getticks() - timeStatic; -#ifdef VERBOSE - printf ("after static\n"); - printImage(OutStatic, "Out"); -#endif - - pifc kernelHL = (pifc)h2_malloc(8192); - ticks_t timeCodeGen = h2_getticks(); - switch (Filter->width) - { - case 1 : kernelHL = genKernel1x1 (kernelHL, Filter->pixelsArray, coeff); break; - case 3 : kernelHL = genKernel3x3 (kernelHL, Filter->pixelsArray, coeff); break; - case 5 : kernelHL = genKernel5x5 (kernelHL, Filter->pixelsArray, coeff); break; - default: printf ("Unknown filter size\n"); exit(-1); - } - timeCodeGen = h2_getticks() - timeCodeGen; - -#ifdef VERBOSE - printf ("after codegen\n"); -#endif - - ticks_t timeH4 = h2_getticks(); // Compilette convolution - for (int i = 0; i < nXperiment; i++) - { - convolutionH4(In, OutH4, Filter, kernelHL); - } - timeH4 = h2_getticks() - timeH4; -#ifdef VERBOSE - printf ("after h2\n"); - printImage(OutH4, "Out H4"); -#endif - error = compareImages(OutH4, OutStatic); - printf("%s;%ix%i;%ix%i;%lld;%lld;%lld;%d;%d\n", - filterImageName, - Filter->width, Filter->height, In->width, In->height, - timeStatic/nXperiment, timeH4/nXperiment, - h2_codeGenTime, h2_insnGenerated, - error); - -#if VERBOSE - writePgmImage(OutStatic, argv[2]); - writePgmImage(OutH4, argv[3]); -#endif - - return (0 == error)?0:-1; -} diff --git a/Demos/Stencil/Stencil.power b/Demos/Stencil/Stencil.power deleted file mode 100755 index 1df4537a7f78e0c90c5bc7ea09c62dc81790da3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145696 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 diff --git a/Demos/Stencil/Stencil.power.c b/Demos/Stencil/Stencil.power.c deleted file mode 100644 index 826cc9f..0000000 --- a/Demos/Stencil/Stencil.power.c +++ /dev/null @@ -1,1955 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define PPC_DIVW_RRR_I_32_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d6 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVD__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x3d3 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO_RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d2 & 0x7ff) >> 0)); } while(0); -#define PPC_DIVDO__RRR_I_64_1(r0,r1,r2) do /* div */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x7d3 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (power)\\n"); - #endif - P2 = power_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_DIVDO__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include -#include -#include -#include "ReadPgmImage.h" - -typedef int (*pifc)(int[], int, int, int); - - -void printImage(imgStruct_t *img, char *imageName) -{ - printf ("ImageName & size: %s %dx%d\n", imageName, img->height, img->width); - for(int line = 0 ; line < img->height ; line++) - { - for(int column = 0 ; column < img->width ; column++) - { - printf("%03d ", img->pixelsArray[line*img->width+column]); - } - printf("\n"); - } - printf("\n"); -} - -int imgSum (imgStruct_t *img) -{ - int line, column, sum; - sum = 0; - for(int line = 0 ; line < img->height ; line++) - { - for(int column = 0 ; column < img->width; column++) - { - sum += img->pixelsArray[line*img->width+column]; - } - } - return (0 == sum)?1:sum; -} - -#if 0 -unsigned char clamp(int value) -{ - return (unsigned char)(0 > value)?0:(255 < value)?255:value; -} -#else -#define clamp(value) ((unsigned char)(0 > value)?0:(255 < value)?255:value) -#endif - -pifc genKernel1x1(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x787F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, line, imgWidth); - tmp0001 = power_genADD_3(tmp0001, tmp0000, column); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = power_genMUL_3(tmp0002, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = power_genADD_3(tmp0003, In, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = power_genR_3(tmp0004, tmp0003, immValueZero); - sum = power_genMUL_3(sum, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); - if (!sum.dontFree) h2_freeReg(tmp0004.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0005 = power_genDIV_3(tmp0005, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -pifc genKernel3x3(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 19 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 17, true}; - h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 18, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7F87F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - njp1 = power_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njm1 = power_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = power_genADD_3(tmp0000, stride, njm1); - tmp0001 = power_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = power_genADD_3(tmp0002, In, tmp0001); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = power_genR_3(tmp0003, tmp0002, immValueZero); - sum = power_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}); - if (!sum.dontFree) h2_freeReg(tmp0003.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0004 = power_genADD_3(tmp0004, stride, column); - tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = power_genADD_3(tmp0006, In, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = power_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = power_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1]))}); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = power_genADD_3(sum, sum, tmp0008); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0009 = power_genADD_3(tmp0009, stride, njp1); - tmp0010 = power_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = power_genADD_3(tmp0011, In, tmp0010); - if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); - tmp0012 = power_genR_3(tmp0012, tmp0011, immValueZero); - tmp0013 = power_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2]))}); - if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); - sum = power_genADD_3(sum, sum, tmp0013); - if (!sum.dontFree) h2_freeReg(tmp0013.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genMV_2(ni, line); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0015 = power_genADD_3(tmp0015, stride, njm1); - tmp0016 = power_genMUL_3(tmp0016, tmp0015, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); - tmp0017 = power_genADD_3(tmp0017, In, tmp0016); - if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); - tmp0018 = power_genR_3(tmp0018, tmp0017, immValueZero); - tmp0019 = power_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+0]))}); - if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); - sum = power_genADD_3(sum, sum, tmp0019); - if (!sum.dontFree) h2_freeReg(tmp0019.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0020 = power_genADD_3(tmp0020, stride, column); - tmp0021 = power_genMUL_3(tmp0021, tmp0020, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); - tmp0022 = power_genADD_3(tmp0022, In, tmp0021); - if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); - tmp0023 = power_genR_3(tmp0023, tmp0022, immValueZero); - tmp0024 = power_genMUL_3(tmp0024, tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+1]))}); - if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); - sum = power_genADD_3(sum, sum, tmp0024); - if (!sum.dontFree) h2_freeReg(tmp0024.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0025 = power_genADD_3(tmp0025, stride, njp1); - tmp0026 = power_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = power_genADD_3(tmp0027, In, tmp0026); - if (!tmp0027.dontFree) h2_freeReg(tmp0026.regNro); - tmp0028 = power_genR_3(tmp0028, tmp0027, immValueZero); - tmp0029 = power_genMUL_3(tmp0029, tmp0028, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+2]))}); - if (!tmp0029.dontFree) h2_freeReg(tmp0028.regNro); - sum = power_genADD_3(sum, sum, tmp0029); - if (!sum.dontFree) h2_freeReg(tmp0029.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0030 = power_genADD_3(tmp0030, stride, njm1); - tmp0031 = power_genMUL_3(tmp0031, tmp0030, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = power_genADD_3(tmp0032, In, tmp0031); - if (!tmp0032.dontFree) h2_freeReg(tmp0031.regNro); - tmp0033 = power_genR_3(tmp0033, tmp0032, immValueZero); - tmp0034 = power_genMUL_3(tmp0034, tmp0033, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+0]))}); - if (!tmp0034.dontFree) h2_freeReg(tmp0033.regNro); - sum = power_genADD_3(sum, sum, tmp0034); - if (!sum.dontFree) h2_freeReg(tmp0034.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0035 = power_genADD_3(tmp0035, stride, column); - tmp0036 = power_genMUL_3(tmp0036, tmp0035, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = power_genADD_3(tmp0037, In, tmp0036); - if (!tmp0037.dontFree) h2_freeReg(tmp0036.regNro); - tmp0038 = power_genR_3(tmp0038, tmp0037, immValueZero); - tmp0039 = power_genMUL_3(tmp0039, tmp0038, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+1]))}); - if (!tmp0039.dontFree) h2_freeReg(tmp0038.regNro); - sum = power_genADD_3(sum, sum, tmp0039); - if (!sum.dontFree) h2_freeReg(tmp0039.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0040 = power_genADD_3(tmp0040, stride, njp1); - tmp0041 = power_genMUL_3(tmp0041, tmp0040, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - tmp0042 = power_genADD_3(tmp0042, In, tmp0041); - if (!tmp0042.dontFree) h2_freeReg(tmp0041.regNro); - tmp0043 = power_genR_3(tmp0043, tmp0042, immValueZero); - tmp0044 = power_genMUL_3(tmp0044, tmp0043, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+2]))}); - if (!tmp0044.dontFree) h2_freeReg(tmp0043.regNro); - sum = power_genADD_3(sum, sum, tmp0044); - if (!sum.dontFree) h2_freeReg(tmp0044.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0045 = power_genDIV_3(tmp0045, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0045); - if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -pifc genKernel5x5(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 41 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t njm2 = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 17, true}; - h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 18, true}; - h2_sValue_t njp2 = {H2REGISTER, 'i', 1, 32, 19, true}; - h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 20, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0084 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0085 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0086 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0087 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0088 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0089 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0090 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0091 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0092 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0093 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0094 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0095 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0096 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0097 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0098 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0099 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0100 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0101 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0102 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0103 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0104 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0105 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0106 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0107 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0108 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0109 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0110 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0111 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0112 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0113 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0114 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0115 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0116 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0117 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0118 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0119 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0120 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0121 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0122 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0123 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0124 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0125 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0126 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1FF87F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - njm2 = power_genSUB_3(njm2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njm1 = power_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njp1 = power_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njp2 = power_genADD_3(njp2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = power_genADD_3(tmp0000, stride, njm2); - tmp0001 = power_genMUL_3(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = power_genADD_3(tmp0002, In, tmp0001); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = power_genR_3(tmp0003, tmp0002, immValueZero); - sum = power_genMUL_3(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+0]))}); - if (!sum.dontFree) h2_freeReg(tmp0003.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0004 = power_genADD_3(tmp0004, stride, njm1); - tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = power_genADD_3(tmp0006, In, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = power_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = power_genMUL_3(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+1]))}); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = power_genADD_3(sum, sum, tmp0008); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0009 = power_genADD_3(tmp0009, stride, column); - tmp0010 = power_genMUL_3(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = power_genADD_3(tmp0011, In, tmp0010); - if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); - tmp0012 = power_genR_3(tmp0012, tmp0011, immValueZero); - tmp0013 = power_genMUL_3(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+2]))}); - if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); - sum = power_genADD_3(sum, sum, tmp0013); - if (!sum.dontFree) h2_freeReg(tmp0013.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0014 = power_genADD_3(tmp0014, stride, njp1); - tmp0015 = power_genMUL_3(tmp0015, tmp0014, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); - tmp0016 = power_genADD_3(tmp0016, In, tmp0015); - if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); - tmp0017 = power_genR_3(tmp0017, tmp0016, immValueZero); - tmp0018 = power_genMUL_3(tmp0018, tmp0017, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+3]))}); - if (!tmp0018.dontFree) h2_freeReg(tmp0017.regNro); - sum = power_genADD_3(sum, sum, tmp0018); - if (!sum.dontFree) h2_freeReg(tmp0018.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0019 = power_genADD_3(tmp0019, stride, njp2); - tmp0020 = power_genMUL_3(tmp0020, tmp0019, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); - tmp0021 = power_genADD_3(tmp0021, In, tmp0020); - if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); - tmp0022 = power_genR_3(tmp0022, tmp0021, immValueZero); - tmp0023 = power_genMUL_3(tmp0023, tmp0022, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+4]))}); - if (!tmp0023.dontFree) h2_freeReg(tmp0022.regNro); - sum = power_genADD_3(sum, sum, tmp0023); - if (!sum.dontFree) h2_freeReg(tmp0023.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0024 = power_genADD_3(tmp0024, stride, njm2); - tmp0025 = power_genMUL_3(tmp0025, tmp0024, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0025.dontFree) h2_freeReg(tmp0024.regNro); - tmp0026 = power_genADD_3(tmp0026, In, tmp0025); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = power_genR_3(tmp0027, tmp0026, immValueZero); - tmp0028 = power_genMUL_3(tmp0028, tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+0]))}); - if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); - sum = power_genADD_3(sum, sum, tmp0028); - if (!sum.dontFree) h2_freeReg(tmp0028.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0029 = power_genADD_3(tmp0029, stride, njm1); - tmp0030 = power_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); - tmp0031 = power_genADD_3(tmp0031, In, tmp0030); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = power_genR_3(tmp0032, tmp0031, immValueZero); - tmp0033 = power_genMUL_3(tmp0033, tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+1]))}); - if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); - sum = power_genADD_3(sum, sum, tmp0033); - if (!sum.dontFree) h2_freeReg(tmp0033.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0034 = power_genADD_3(tmp0034, stride, column); - tmp0035 = power_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); - tmp0036 = power_genADD_3(tmp0036, In, tmp0035); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = power_genR_3(tmp0037, tmp0036, immValueZero); - tmp0038 = power_genMUL_3(tmp0038, tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+2]))}); - if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); - sum = power_genADD_3(sum, sum, tmp0038); - if (!sum.dontFree) h2_freeReg(tmp0038.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0039 = power_genADD_3(tmp0039, stride, njp1); - tmp0040 = power_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); - tmp0041 = power_genADD_3(tmp0041, In, tmp0040); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - tmp0042 = power_genR_3(tmp0042, tmp0041, immValueZero); - tmp0043 = power_genMUL_3(tmp0043, tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+3]))}); - if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); - sum = power_genADD_3(sum, sum, tmp0043); - if (!sum.dontFree) h2_freeReg(tmp0043.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0044 = power_genADD_3(tmp0044, stride, njp2); - tmp0045 = power_genMUL_3(tmp0045, tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); - tmp0046 = power_genADD_3(tmp0046, In, tmp0045); - if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); - tmp0047 = power_genR_3(tmp0047, tmp0046, immValueZero); - tmp0048 = power_genMUL_3(tmp0048, tmp0047, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+4]))}); - if (!tmp0048.dontFree) h2_freeReg(tmp0047.regNro); - sum = power_genADD_3(sum, sum, tmp0048); - if (!sum.dontFree) h2_freeReg(tmp0048.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genMV_2(ni, line); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0050 = power_genADD_3(tmp0050, stride, njm2); - tmp0051 = power_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); - tmp0052 = power_genADD_3(tmp0052, In, tmp0051); - if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); - tmp0053 = power_genR_3(tmp0053, tmp0052, immValueZero); - tmp0054 = power_genMUL_3(tmp0054, tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+0]))}); - if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); - sum = power_genADD_3(sum, sum, tmp0054); - if (!sum.dontFree) h2_freeReg(tmp0054.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0055 = power_genADD_3(tmp0055, stride, njm1); - tmp0056 = power_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); - tmp0057 = power_genADD_3(tmp0057, In, tmp0056); - if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); - tmp0058 = power_genR_3(tmp0058, tmp0057, immValueZero); - tmp0059 = power_genMUL_3(tmp0059, tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+1]))}); - if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); - sum = power_genADD_3(sum, sum, tmp0059); - if (!sum.dontFree) h2_freeReg(tmp0059.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0060 = power_genADD_3(tmp0060, stride, column); - tmp0061 = power_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); - tmp0062 = power_genADD_3(tmp0062, In, tmp0061); - if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); - tmp0063 = power_genR_3(tmp0063, tmp0062, immValueZero); - tmp0064 = power_genMUL_3(tmp0064, tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+2]))}); - if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); - sum = power_genADD_3(sum, sum, tmp0064); - if (!sum.dontFree) h2_freeReg(tmp0064.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0065 = power_genADD_3(tmp0065, stride, njp1); - tmp0066 = power_genMUL_3(tmp0066, tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); - tmp0067 = power_genADD_3(tmp0067, In, tmp0066); - if (!tmp0067.dontFree) h2_freeReg(tmp0066.regNro); - tmp0068 = power_genR_3(tmp0068, tmp0067, immValueZero); - tmp0069 = power_genMUL_3(tmp0069, tmp0068, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+3]))}); - if (!tmp0069.dontFree) h2_freeReg(tmp0068.regNro); - sum = power_genADD_3(sum, sum, tmp0069); - if (!sum.dontFree) h2_freeReg(tmp0069.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0070 = power_genADD_3(tmp0070, stride, njp2); - tmp0071 = power_genMUL_3(tmp0071, tmp0070, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0071.dontFree) h2_freeReg(tmp0070.regNro); - tmp0072 = power_genADD_3(tmp0072, In, tmp0071); - if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); - tmp0073 = power_genR_3(tmp0073, tmp0072, immValueZero); - tmp0074 = power_genMUL_3(tmp0074, tmp0073, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+4]))}); - if (!tmp0074.dontFree) h2_freeReg(tmp0073.regNro); - sum = power_genADD_3(sum, sum, tmp0074); - if (!sum.dontFree) h2_freeReg(tmp0074.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0075 = power_genADD_3(tmp0075, stride, njm2); - tmp0076 = power_genMUL_3(tmp0076, tmp0075, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0076.dontFree) h2_freeReg(tmp0075.regNro); - tmp0077 = power_genADD_3(tmp0077, In, tmp0076); - if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); - tmp0078 = power_genR_3(tmp0078, tmp0077, immValueZero); - tmp0079 = power_genMUL_3(tmp0079, tmp0078, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+0]))}); - if (!tmp0079.dontFree) h2_freeReg(tmp0078.regNro); - sum = power_genADD_3(sum, sum, tmp0079); - if (!sum.dontFree) h2_freeReg(tmp0079.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0080 = power_genADD_3(tmp0080, stride, njm1); - tmp0081 = power_genMUL_3(tmp0081, tmp0080, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0081.dontFree) h2_freeReg(tmp0080.regNro); - tmp0082 = power_genADD_3(tmp0082, In, tmp0081); - if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); - tmp0083 = power_genR_3(tmp0083, tmp0082, immValueZero); - tmp0084 = power_genMUL_3(tmp0084, tmp0083, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+1]))}); - if (!tmp0084.dontFree) h2_freeReg(tmp0083.regNro); - sum = power_genADD_3(sum, sum, tmp0084); - if (!sum.dontFree) h2_freeReg(tmp0084.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0085 = power_genADD_3(tmp0085, stride, column); - tmp0086 = power_genMUL_3(tmp0086, tmp0085, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0086.dontFree) h2_freeReg(tmp0085.regNro); - tmp0087 = power_genADD_3(tmp0087, In, tmp0086); - if (!tmp0087.dontFree) h2_freeReg(tmp0086.regNro); - tmp0088 = power_genR_3(tmp0088, tmp0087, immValueZero); - tmp0089 = power_genMUL_3(tmp0089, tmp0088, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+2]))}); - if (!tmp0089.dontFree) h2_freeReg(tmp0088.regNro); - sum = power_genADD_3(sum, sum, tmp0089); - if (!sum.dontFree) h2_freeReg(tmp0089.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0090 = power_genADD_3(tmp0090, stride, njp1); - tmp0091 = power_genMUL_3(tmp0091, tmp0090, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0091.dontFree) h2_freeReg(tmp0090.regNro); - tmp0092 = power_genADD_3(tmp0092, In, tmp0091); - if (!tmp0092.dontFree) h2_freeReg(tmp0091.regNro); - tmp0093 = power_genR_3(tmp0093, tmp0092, immValueZero); - tmp0094 = power_genMUL_3(tmp0094, tmp0093, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+3]))}); - if (!tmp0094.dontFree) h2_freeReg(tmp0093.regNro); - sum = power_genADD_3(sum, sum, tmp0094); - if (!sum.dontFree) h2_freeReg(tmp0094.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0095 = power_genADD_3(tmp0095, stride, njp2); - tmp0096 = power_genMUL_3(tmp0096, tmp0095, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0096.dontFree) h2_freeReg(tmp0095.regNro); - tmp0097 = power_genADD_3(tmp0097, In, tmp0096); - if (!tmp0097.dontFree) h2_freeReg(tmp0096.regNro); - tmp0098 = power_genR_3(tmp0098, tmp0097, immValueZero); - tmp0099 = power_genMUL_3(tmp0099, tmp0098, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+4]))}); - if (!tmp0099.dontFree) h2_freeReg(tmp0098.regNro); - sum = power_genADD_3(sum, sum, tmp0099); - if (!sum.dontFree) h2_freeReg(tmp0099.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = power_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = power_genMUL_3(stride, ni, imgWidth); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0100 = power_genADD_3(tmp0100, stride, njm2); - tmp0101 = power_genMUL_3(tmp0101, tmp0100, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0101.dontFree) h2_freeReg(tmp0100.regNro); - tmp0102 = power_genADD_3(tmp0102, In, tmp0101); - if (!tmp0102.dontFree) h2_freeReg(tmp0101.regNro); - tmp0103 = power_genR_3(tmp0103, tmp0102, immValueZero); - tmp0104 = power_genMUL_3(tmp0104, tmp0103, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+0]))}); - if (!tmp0104.dontFree) h2_freeReg(tmp0103.regNro); - sum = power_genADD_3(sum, sum, tmp0104); - if (!sum.dontFree) h2_freeReg(tmp0104.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0105 = power_genADD_3(tmp0105, stride, njm1); - tmp0106 = power_genMUL_3(tmp0106, tmp0105, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0106.dontFree) h2_freeReg(tmp0105.regNro); - tmp0107 = power_genADD_3(tmp0107, In, tmp0106); - if (!tmp0107.dontFree) h2_freeReg(tmp0106.regNro); - tmp0108 = power_genR_3(tmp0108, tmp0107, immValueZero); - tmp0109 = power_genMUL_3(tmp0109, tmp0108, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+1]))}); - if (!tmp0109.dontFree) h2_freeReg(tmp0108.regNro); - sum = power_genADD_3(sum, sum, tmp0109); - if (!sum.dontFree) h2_freeReg(tmp0109.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0110 = power_genADD_3(tmp0110, stride, column); - tmp0111 = power_genMUL_3(tmp0111, tmp0110, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0111.dontFree) h2_freeReg(tmp0110.regNro); - tmp0112 = power_genADD_3(tmp0112, In, tmp0111); - if (!tmp0112.dontFree) h2_freeReg(tmp0111.regNro); - tmp0113 = power_genR_3(tmp0113, tmp0112, immValueZero); - tmp0114 = power_genMUL_3(tmp0114, tmp0113, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+2]))}); - if (!tmp0114.dontFree) h2_freeReg(tmp0113.regNro); - sum = power_genADD_3(sum, sum, tmp0114); - if (!sum.dontFree) h2_freeReg(tmp0114.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0115 = power_genADD_3(tmp0115, stride, njp1); - tmp0116 = power_genMUL_3(tmp0116, tmp0115, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0116.dontFree) h2_freeReg(tmp0115.regNro); - tmp0117 = power_genADD_3(tmp0117, In, tmp0116); - if (!tmp0117.dontFree) h2_freeReg(tmp0116.regNro); - tmp0118 = power_genR_3(tmp0118, tmp0117, immValueZero); - tmp0119 = power_genMUL_3(tmp0119, tmp0118, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+3]))}); - if (!tmp0119.dontFree) h2_freeReg(tmp0118.regNro); - sum = power_genADD_3(sum, sum, tmp0119); - if (!sum.dontFree) h2_freeReg(tmp0119.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0120 = power_genADD_3(tmp0120, stride, njp2); - tmp0121 = power_genMUL_3(tmp0121, tmp0120, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - if (!tmp0121.dontFree) h2_freeReg(tmp0120.regNro); - tmp0122 = power_genADD_3(tmp0122, In, tmp0121); - if (!tmp0122.dontFree) h2_freeReg(tmp0121.regNro); - tmp0123 = power_genR_3(tmp0123, tmp0122, immValueZero); - tmp0124 = power_genMUL_3(tmp0124, tmp0123, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+4]))}); - if (!tmp0124.dontFree) h2_freeReg(tmp0123.regNro); - sum = power_genADD_3(sum, sum, tmp0124); - if (!sum.dontFree) h2_freeReg(tmp0124.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0125 = power_genDIV_3(tmp0125, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}); - h2_outputVarName = power_genMV_2(h2_outputVarName, tmp0125); - if (!tmp0126.dontFree) h2_freeReg(tmp0125.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -#if 0 -#endif -} - -// Compute a stencil for 1 point -int kernelStatic(imgStruct_t *In, int l, int c, imgStruct_t *Filter, int coeff) -{ - int line, column, sum = 0; - int offset = (Filter->width)/2; - - for (line = 0; line < Filter->height; line++) - { - for (column = 0; column < Filter->width; column++) - { - int ni = (l + line) - offset; - int nj = (c + column) - offset; - sum += In->pixelsArray[ni*In->width+nj] * Filter->pixelsArray[line*Filter->width+column]; - } - } - return sum / coeff; -} - - -void convolutionStatic(imgStruct_t *In, imgStruct_t *Out, imgStruct_t *Filter, int coeff) -{ - int offset = Filter->width/2; - int result; - for (int line = offset; line < In->height - offset; line++) - { - for (int column = offset; column < In->width - offset; column++) - { - result = kernelStatic(In, line, column, Filter, coeff); - Out->pixelsArray[line*Out->width+column] = clamp(result); - } - } -} - -void convolutionH4(imgStruct_t* In, imgStruct_t *Out, imgStruct_t *Filter, pifc kernelHL) -{ - int offset = Filter->width/2; - int result; - for (int line = offset; line < In->height - offset; line++) - { - for (int column = offset; column < In->width - offset; column++) - { - result = kernelHL(In->pixelsArray, line, column, In->width); - Out->pixelsArray[line*Out->width+column] = clamp(result); - } - } -} - -int compareImages(imgStruct_t *staticImg, imgStruct_t *H4Img) -{ - int errors = 0; - for(int line = 0 ; line < staticImg->height ; line++) - { - for(int column = 0 ; column < staticImg->width ; column++) - { - if((staticImg->pixelsArray[line*staticImg->width+column] - H4Img->pixelsArray[line*H4Img->width+column]) != 0) - { - if (0 == errors) - { - printf("Alert : first difference at line %i column %i\n", line, column); - } - errors++; - } - } - } - return errors; -} - -int main(int argc, char *argv[]) -{ - int error, coeff, nXperiment = 20; - imgStruct_t *In, *OutH4, *OutStatic, *Filter; - char *filterImageName, *inputImageName; - if (argc < 5) - { - printf ("./Stencil \n"); - exit(-1); - } - - inputImageName = argv[1]; - filterImageName = argv[4]; - In = readPgmImage(inputImageName); - Filter = readPgmImage(filterImageName); - coeff = imgSum (Filter); -#ifdef VERBOSE - printf ("%s: coeff %d\n", filterImageName, coeff); - printImage (Filter, "Filter"); -#endif - assert (Filter->width == Filter->height); // Only square filters - OutStatic = createImage (In->height, In->width); - OutH4 = createImage (In->height, In->width); -#ifdef VERBOSE - printf ("after init\n"); - printImage(In, "In"); -#endif - ticks_t timeStatic = h2_getticks(); // Static convolution - for (int i = 0; i < nXperiment; i++) - { - convolutionStatic(In, OutStatic, Filter, coeff); - } - timeStatic = h2_getticks() - timeStatic; -#ifdef VERBOSE - printf ("after static\n"); - printImage(OutStatic, "Out"); -#endif - - pifc kernelHL = (pifc)h2_malloc(8192); - ticks_t timeCodeGen = h2_getticks(); - switch (Filter->width) - { - case 1 : kernelHL = genKernel1x1 (kernelHL, Filter->pixelsArray, coeff); break; - case 3 : kernelHL = genKernel3x3 (kernelHL, Filter->pixelsArray, coeff); break; - case 5 : kernelHL = genKernel5x5 (kernelHL, Filter->pixelsArray, coeff); break; - default: printf ("Unknown filter size\n"); exit(-1); - } - timeCodeGen = h2_getticks() - timeCodeGen; - -#ifdef VERBOSE - printf ("after codegen\n"); -#endif - - ticks_t timeH4 = h2_getticks(); // Compilette convolution - for (int i = 0; i < nXperiment; i++) - { - convolutionH4(In, OutH4, Filter, kernelHL); - } - timeH4 = h2_getticks() - timeH4; -#ifdef VERBOSE - printf ("after h2\n"); - printImage(OutH4, "Out H4"); -#endif - error = compareImages(OutH4, OutStatic); - printf("%s;%ix%i;%ix%i;%lld;%lld;%lld;%d;%d\n", - filterImageName, - Filter->width, Filter->height, In->width, In->height, - timeStatic/nXperiment, timeH4/nXperiment, - h2_codeGenTime, h2_insnGenerated, - error); - -#if VERBOSE - writePgmImage(OutStatic, argv[2]); - writePgmImage(OutH4, argv[3]); -#endif - - return (0 == error)?0:-1; -} diff --git a/Demos/Stencil/Stencil.riscv b/Demos/Stencil/Stencil.riscv deleted file mode 100755 index 60c93461d991da91012ba0558f9cc14c29dff531..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171700 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 pi1M{K83zqG`II-}2GMezEw)DHk -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32M_DIV_RRR_I_32_1(r3,r1,r2) do /* DIV */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x4 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genDIV_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) - { // RISCV has no DIVI - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { // X * NPowerOf2 = X >> N (immediate shift left) - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSR_3(P0, P1, P2); - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_DIV_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include -#include -#include -#include "ReadPgmImage.h" - -typedef int (*pifc)(int[], int, int, int); - - -void printImage(imgStruct_t *img, char *imageName) -{ - printf ("ImageName & size: %s %dx%d\n", imageName, img->height, img->width); - for(int line = 0 ; line < img->height ; line++) - { - for(int column = 0 ; column < img->width ; column++) - { - printf("%03d ", img->pixelsArray[line*img->width+column]); - } - printf("\n"); - } - printf("\n"); -} - -int imgSum (imgStruct_t *img) -{ - int line, column, sum; - sum = 0; - for(int line = 0 ; line < img->height ; line++) - { - for(int column = 0 ; column < img->width; column++) - { - sum += img->pixelsArray[line*img->width+column]; - } - } - return (0 == sum)?1:sum; -} - -#if 0 -unsigned char clamp(int value) -{ - return (unsigned char)(0 > value)?0:(255 < value)?255:value; -} -#else -#define clamp(value) ((unsigned char)(0 > value)?0:(255 < value)?255:value) -#endif - -pifc genKernel1x1(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 13, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x3F3F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, line, imgWidth, immValueZero); - tmp0001 = riscv_genADD_3(tmp0001, tmp0000, column); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = riscv_genMUL_4(tmp0002, tmp0001, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = riscv_genADD_3(tmp0003, In, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = riscv_genR_3(tmp0004, tmp0003, immValueZero); - sum = riscv_genMUL_4(sum, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}, immValueZero); - if (!sum.dontFree) h2_freeReg(tmp0004.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0005 = riscv_genDIV_4(tmp0005, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}, immValueZero); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -pifc genKernel3x3(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 19 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 13, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 28, true}; - h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 29, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x30003FFF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - njp1 = riscv_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njm1 = riscv_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = riscv_genADD_3(tmp0000, stride, njm1); - tmp0001 = riscv_genMUL_4(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = riscv_genADD_3(tmp0002, In, tmp0001); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = riscv_genR_3(tmp0003, tmp0002, immValueZero); - sum = riscv_genMUL_4(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0]))}, immValueZero); - if (!sum.dontFree) h2_freeReg(tmp0003.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0004 = riscv_genADD_3(tmp0004, stride, column); - tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = riscv_genADD_3(tmp0006, In, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = riscv_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = riscv_genMUL_4(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1]))}, immValueZero); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = riscv_genADD_3(sum, sum, tmp0008); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0009 = riscv_genADD_3(tmp0009, stride, njp1); - tmp0010 = riscv_genMUL_4(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = riscv_genADD_3(tmp0011, In, tmp0010); - if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); - tmp0012 = riscv_genR_3(tmp0012, tmp0011, immValueZero); - tmp0013 = riscv_genMUL_4(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2]))}, immValueZero); - if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); - sum = riscv_genADD_3(sum, sum, tmp0013); - if (!sum.dontFree) h2_freeReg(tmp0013.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genMV_2(ni, line); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0015 = riscv_genADD_3(tmp0015, stride, njm1); - tmp0016 = riscv_genMUL_4(tmp0016, tmp0015, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); - tmp0017 = riscv_genADD_3(tmp0017, In, tmp0016); - if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); - tmp0018 = riscv_genR_3(tmp0018, tmp0017, immValueZero); - tmp0019 = riscv_genMUL_4(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+0]))}, immValueZero); - if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); - sum = riscv_genADD_3(sum, sum, tmp0019); - if (!sum.dontFree) h2_freeReg(tmp0019.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0020 = riscv_genADD_3(tmp0020, stride, column); - tmp0021 = riscv_genMUL_4(tmp0021, tmp0020, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); - tmp0022 = riscv_genADD_3(tmp0022, In, tmp0021); - if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); - tmp0023 = riscv_genR_3(tmp0023, tmp0022, immValueZero); - tmp0024 = riscv_genMUL_4(tmp0024, tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+1]))}, immValueZero); - if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); - sum = riscv_genADD_3(sum, sum, tmp0024); - if (!sum.dontFree) h2_freeReg(tmp0024.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0025 = riscv_genADD_3(tmp0025, stride, njp1); - tmp0026 = riscv_genMUL_4(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = riscv_genADD_3(tmp0027, In, tmp0026); - if (!tmp0027.dontFree) h2_freeReg(tmp0026.regNro); - tmp0028 = riscv_genR_3(tmp0028, tmp0027, immValueZero); - tmp0029 = riscv_genMUL_4(tmp0029, tmp0028, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*3+2]))}, immValueZero); - if (!tmp0029.dontFree) h2_freeReg(tmp0028.regNro); - sum = riscv_genADD_3(sum, sum, tmp0029); - if (!sum.dontFree) h2_freeReg(tmp0029.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0030 = riscv_genADD_3(tmp0030, stride, njm1); - tmp0031 = riscv_genMUL_4(tmp0031, tmp0030, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = riscv_genADD_3(tmp0032, In, tmp0031); - if (!tmp0032.dontFree) h2_freeReg(tmp0031.regNro); - tmp0033 = riscv_genR_3(tmp0033, tmp0032, immValueZero); - tmp0034 = riscv_genMUL_4(tmp0034, tmp0033, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+0]))}, immValueZero); - if (!tmp0034.dontFree) h2_freeReg(tmp0033.regNro); - sum = riscv_genADD_3(sum, sum, tmp0034); - if (!sum.dontFree) h2_freeReg(tmp0034.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0035 = riscv_genADD_3(tmp0035, stride, column); - tmp0036 = riscv_genMUL_4(tmp0036, tmp0035, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = riscv_genADD_3(tmp0037, In, tmp0036); - if (!tmp0037.dontFree) h2_freeReg(tmp0036.regNro); - tmp0038 = riscv_genR_3(tmp0038, tmp0037, immValueZero); - tmp0039 = riscv_genMUL_4(tmp0039, tmp0038, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+1]))}, immValueZero); - if (!tmp0039.dontFree) h2_freeReg(tmp0038.regNro); - sum = riscv_genADD_3(sum, sum, tmp0039); - if (!sum.dontFree) h2_freeReg(tmp0039.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0040 = riscv_genADD_3(tmp0040, stride, njp1); - tmp0041 = riscv_genMUL_4(tmp0041, tmp0040, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - tmp0042 = riscv_genADD_3(tmp0042, In, tmp0041); - if (!tmp0042.dontFree) h2_freeReg(tmp0041.regNro); - tmp0043 = riscv_genR_3(tmp0043, tmp0042, immValueZero); - tmp0044 = riscv_genMUL_4(tmp0044, tmp0043, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*3+2]))}, immValueZero); - if (!tmp0044.dontFree) h2_freeReg(tmp0043.regNro); - sum = riscv_genADD_3(sum, sum, tmp0044); - if (!sum.dontFree) h2_freeReg(tmp0044.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0045 = riscv_genDIV_4(tmp0045, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}, immValueZero); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0045); - if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -pifc genKernel5x5(pifc ptr, int* Filter, int coeff) -{ - /* Code Generation of 41 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t In = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t line = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t column = {H2REGISTER, 'i', 1, 32, 12, true}; - h2_sValue_t imgWidth = {H2REGISTER, 'i', 1, 32, 13, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t sum = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t ni = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t njm2 = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t njm1 = {H2REGISTER, 'i', 1, 32, 28, true}; - h2_sValue_t njp1 = {H2REGISTER, 'i', 1, 32, 29, true}; - h2_sValue_t njp2 = {H2REGISTER, 'i', 1, 32, 30, true}; - h2_sValue_t stride = {H2REGISTER, 'i', 1, 32, 31, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0084 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0085 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0086 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0087 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0088 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0089 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0090 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0091 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0092 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0093 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0094 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0095 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0096 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0097 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0098 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0099 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0100 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0101 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0102 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0103 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0104 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0105 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0106 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0107 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0108 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0109 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0110 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0111 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0112 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0113 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0114 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0115 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0116 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0117 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0118 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0119 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0120 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0121 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0122 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0123 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0124 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0125 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0126 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF0003FFF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - njm2 = riscv_genSUB_3(njm2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njm1 = riscv_genSUB_3(njm1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njp1 = riscv_genADD_3(njp1, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - njp2 = riscv_genADD_3(njp2, column, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0000 = riscv_genADD_3(tmp0000, stride, njm2); - tmp0001 = riscv_genMUL_4(tmp0001, tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = riscv_genADD_3(tmp0002, In, tmp0001); - if (!tmp0002.dontFree) h2_freeReg(tmp0001.regNro); - tmp0003 = riscv_genR_3(tmp0003, tmp0002, immValueZero); - sum = riscv_genMUL_4(sum, tmp0003, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+0]))}, immValueZero); - if (!sum.dontFree) h2_freeReg(tmp0003.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0004 = riscv_genADD_3(tmp0004, stride, njm1); - tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = riscv_genADD_3(tmp0006, In, tmp0005); - if (!tmp0006.dontFree) h2_freeReg(tmp0005.regNro); - tmp0007 = riscv_genR_3(tmp0007, tmp0006, immValueZero); - tmp0008 = riscv_genMUL_4(tmp0008, tmp0007, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+1]))}, immValueZero); - if (!tmp0008.dontFree) h2_freeReg(tmp0007.regNro); - sum = riscv_genADD_3(sum, sum, tmp0008); - if (!sum.dontFree) h2_freeReg(tmp0008.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0009 = riscv_genADD_3(tmp0009, stride, column); - tmp0010 = riscv_genMUL_4(tmp0010, tmp0009, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = riscv_genADD_3(tmp0011, In, tmp0010); - if (!tmp0011.dontFree) h2_freeReg(tmp0010.regNro); - tmp0012 = riscv_genR_3(tmp0012, tmp0011, immValueZero); - tmp0013 = riscv_genMUL_4(tmp0013, tmp0012, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+2]))}, immValueZero); - if (!tmp0013.dontFree) h2_freeReg(tmp0012.regNro); - sum = riscv_genADD_3(sum, sum, tmp0013); - if (!sum.dontFree) h2_freeReg(tmp0013.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0014 = riscv_genADD_3(tmp0014, stride, njp1); - tmp0015 = riscv_genMUL_4(tmp0015, tmp0014, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); - tmp0016 = riscv_genADD_3(tmp0016, In, tmp0015); - if (!tmp0016.dontFree) h2_freeReg(tmp0015.regNro); - tmp0017 = riscv_genR_3(tmp0017, tmp0016, immValueZero); - tmp0018 = riscv_genMUL_4(tmp0018, tmp0017, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+3]))}, immValueZero); - if (!tmp0018.dontFree) h2_freeReg(tmp0017.regNro); - sum = riscv_genADD_3(sum, sum, tmp0018); - if (!sum.dontFree) h2_freeReg(tmp0018.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0019 = riscv_genADD_3(tmp0019, stride, njp2); - tmp0020 = riscv_genMUL_4(tmp0020, tmp0019, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); - tmp0021 = riscv_genADD_3(tmp0021, In, tmp0020); - if (!tmp0021.dontFree) h2_freeReg(tmp0020.regNro); - tmp0022 = riscv_genR_3(tmp0022, tmp0021, immValueZero); - tmp0023 = riscv_genMUL_4(tmp0023, tmp0022, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[0*5+4]))}, immValueZero); - if (!tmp0023.dontFree) h2_freeReg(tmp0022.regNro); - sum = riscv_genADD_3(sum, sum, tmp0023); - if (!sum.dontFree) h2_freeReg(tmp0023.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genSUB_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0024 = riscv_genADD_3(tmp0024, stride, njm2); - tmp0025 = riscv_genMUL_4(tmp0025, tmp0024, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0025.dontFree) h2_freeReg(tmp0024.regNro); - tmp0026 = riscv_genADD_3(tmp0026, In, tmp0025); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = riscv_genR_3(tmp0027, tmp0026, immValueZero); - tmp0028 = riscv_genMUL_4(tmp0028, tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+0]))}, immValueZero); - if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); - sum = riscv_genADD_3(sum, sum, tmp0028); - if (!sum.dontFree) h2_freeReg(tmp0028.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0029 = riscv_genADD_3(tmp0029, stride, njm1); - tmp0030 = riscv_genMUL_4(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); - tmp0031 = riscv_genADD_3(tmp0031, In, tmp0030); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = riscv_genR_3(tmp0032, tmp0031, immValueZero); - tmp0033 = riscv_genMUL_4(tmp0033, tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+1]))}, immValueZero); - if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); - sum = riscv_genADD_3(sum, sum, tmp0033); - if (!sum.dontFree) h2_freeReg(tmp0033.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0034 = riscv_genADD_3(tmp0034, stride, column); - tmp0035 = riscv_genMUL_4(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); - tmp0036 = riscv_genADD_3(tmp0036, In, tmp0035); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = riscv_genR_3(tmp0037, tmp0036, immValueZero); - tmp0038 = riscv_genMUL_4(tmp0038, tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+2]))}, immValueZero); - if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); - sum = riscv_genADD_3(sum, sum, tmp0038); - if (!sum.dontFree) h2_freeReg(tmp0038.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0039 = riscv_genADD_3(tmp0039, stride, njp1); - tmp0040 = riscv_genMUL_4(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); - tmp0041 = riscv_genADD_3(tmp0041, In, tmp0040); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - tmp0042 = riscv_genR_3(tmp0042, tmp0041, immValueZero); - tmp0043 = riscv_genMUL_4(tmp0043, tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+3]))}, immValueZero); - if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); - sum = riscv_genADD_3(sum, sum, tmp0043); - if (!sum.dontFree) h2_freeReg(tmp0043.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0044 = riscv_genADD_3(tmp0044, stride, njp2); - tmp0045 = riscv_genMUL_4(tmp0045, tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); - tmp0046 = riscv_genADD_3(tmp0046, In, tmp0045); - if (!tmp0046.dontFree) h2_freeReg(tmp0045.regNro); - tmp0047 = riscv_genR_3(tmp0047, tmp0046, immValueZero); - tmp0048 = riscv_genMUL_4(tmp0048, tmp0047, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[1*5+4]))}, immValueZero); - if (!tmp0048.dontFree) h2_freeReg(tmp0047.regNro); - sum = riscv_genADD_3(sum, sum, tmp0048); - if (!sum.dontFree) h2_freeReg(tmp0048.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genMV_2(ni, line); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0050 = riscv_genADD_3(tmp0050, stride, njm2); - tmp0051 = riscv_genMUL_4(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); - tmp0052 = riscv_genADD_3(tmp0052, In, tmp0051); - if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); - tmp0053 = riscv_genR_3(tmp0053, tmp0052, immValueZero); - tmp0054 = riscv_genMUL_4(tmp0054, tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+0]))}, immValueZero); - if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); - sum = riscv_genADD_3(sum, sum, tmp0054); - if (!sum.dontFree) h2_freeReg(tmp0054.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0055 = riscv_genADD_3(tmp0055, stride, njm1); - tmp0056 = riscv_genMUL_4(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); - tmp0057 = riscv_genADD_3(tmp0057, In, tmp0056); - if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); - tmp0058 = riscv_genR_3(tmp0058, tmp0057, immValueZero); - tmp0059 = riscv_genMUL_4(tmp0059, tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+1]))}, immValueZero); - if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); - sum = riscv_genADD_3(sum, sum, tmp0059); - if (!sum.dontFree) h2_freeReg(tmp0059.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0060 = riscv_genADD_3(tmp0060, stride, column); - tmp0061 = riscv_genMUL_4(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); - tmp0062 = riscv_genADD_3(tmp0062, In, tmp0061); - if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); - tmp0063 = riscv_genR_3(tmp0063, tmp0062, immValueZero); - tmp0064 = riscv_genMUL_4(tmp0064, tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+2]))}, immValueZero); - if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); - sum = riscv_genADD_3(sum, sum, tmp0064); - if (!sum.dontFree) h2_freeReg(tmp0064.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0065 = riscv_genADD_3(tmp0065, stride, njp1); - tmp0066 = riscv_genMUL_4(tmp0066, tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); - tmp0067 = riscv_genADD_3(tmp0067, In, tmp0066); - if (!tmp0067.dontFree) h2_freeReg(tmp0066.regNro); - tmp0068 = riscv_genR_3(tmp0068, tmp0067, immValueZero); - tmp0069 = riscv_genMUL_4(tmp0069, tmp0068, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+3]))}, immValueZero); - if (!tmp0069.dontFree) h2_freeReg(tmp0068.regNro); - sum = riscv_genADD_3(sum, sum, tmp0069); - if (!sum.dontFree) h2_freeReg(tmp0069.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0070 = riscv_genADD_3(tmp0070, stride, njp2); - tmp0071 = riscv_genMUL_4(tmp0071, tmp0070, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0071.dontFree) h2_freeReg(tmp0070.regNro); - tmp0072 = riscv_genADD_3(tmp0072, In, tmp0071); - if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); - tmp0073 = riscv_genR_3(tmp0073, tmp0072, immValueZero); - tmp0074 = riscv_genMUL_4(tmp0074, tmp0073, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[2*5+4]))}, immValueZero); - if (!tmp0074.dontFree) h2_freeReg(tmp0073.regNro); - sum = riscv_genADD_3(sum, sum, tmp0074); - if (!sum.dontFree) h2_freeReg(tmp0074.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0075 = riscv_genADD_3(tmp0075, stride, njm2); - tmp0076 = riscv_genMUL_4(tmp0076, tmp0075, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0076.dontFree) h2_freeReg(tmp0075.regNro); - tmp0077 = riscv_genADD_3(tmp0077, In, tmp0076); - if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); - tmp0078 = riscv_genR_3(tmp0078, tmp0077, immValueZero); - tmp0079 = riscv_genMUL_4(tmp0079, tmp0078, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+0]))}, immValueZero); - if (!tmp0079.dontFree) h2_freeReg(tmp0078.regNro); - sum = riscv_genADD_3(sum, sum, tmp0079); - if (!sum.dontFree) h2_freeReg(tmp0079.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0080 = riscv_genADD_3(tmp0080, stride, njm1); - tmp0081 = riscv_genMUL_4(tmp0081, tmp0080, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0081.dontFree) h2_freeReg(tmp0080.regNro); - tmp0082 = riscv_genADD_3(tmp0082, In, tmp0081); - if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); - tmp0083 = riscv_genR_3(tmp0083, tmp0082, immValueZero); - tmp0084 = riscv_genMUL_4(tmp0084, tmp0083, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+1]))}, immValueZero); - if (!tmp0084.dontFree) h2_freeReg(tmp0083.regNro); - sum = riscv_genADD_3(sum, sum, tmp0084); - if (!sum.dontFree) h2_freeReg(tmp0084.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0085 = riscv_genADD_3(tmp0085, stride, column); - tmp0086 = riscv_genMUL_4(tmp0086, tmp0085, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0086.dontFree) h2_freeReg(tmp0085.regNro); - tmp0087 = riscv_genADD_3(tmp0087, In, tmp0086); - if (!tmp0087.dontFree) h2_freeReg(tmp0086.regNro); - tmp0088 = riscv_genR_3(tmp0088, tmp0087, immValueZero); - tmp0089 = riscv_genMUL_4(tmp0089, tmp0088, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+2]))}, immValueZero); - if (!tmp0089.dontFree) h2_freeReg(tmp0088.regNro); - sum = riscv_genADD_3(sum, sum, tmp0089); - if (!sum.dontFree) h2_freeReg(tmp0089.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0090 = riscv_genADD_3(tmp0090, stride, njp1); - tmp0091 = riscv_genMUL_4(tmp0091, tmp0090, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0091.dontFree) h2_freeReg(tmp0090.regNro); - tmp0092 = riscv_genADD_3(tmp0092, In, tmp0091); - if (!tmp0092.dontFree) h2_freeReg(tmp0091.regNro); - tmp0093 = riscv_genR_3(tmp0093, tmp0092, immValueZero); - tmp0094 = riscv_genMUL_4(tmp0094, tmp0093, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+3]))}, immValueZero); - if (!tmp0094.dontFree) h2_freeReg(tmp0093.regNro); - sum = riscv_genADD_3(sum, sum, tmp0094); - if (!sum.dontFree) h2_freeReg(tmp0094.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0095 = riscv_genADD_3(tmp0095, stride, njp2); - tmp0096 = riscv_genMUL_4(tmp0096, tmp0095, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0096.dontFree) h2_freeReg(tmp0095.regNro); - tmp0097 = riscv_genADD_3(tmp0097, In, tmp0096); - if (!tmp0097.dontFree) h2_freeReg(tmp0096.regNro); - tmp0098 = riscv_genR_3(tmp0098, tmp0097, immValueZero); - tmp0099 = riscv_genMUL_4(tmp0099, tmp0098, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[3*5+4]))}, immValueZero); - if (!tmp0099.dontFree) h2_freeReg(tmp0098.regNro); - sum = riscv_genADD_3(sum, sum, tmp0099); - if (!sum.dontFree) h2_freeReg(tmp0099.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - ni = riscv_genADD_3(ni, line, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - stride = riscv_genMUL_4(stride, ni, imgWidth, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0100 = riscv_genADD_3(tmp0100, stride, njm2); - tmp0101 = riscv_genMUL_4(tmp0101, tmp0100, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0101.dontFree) h2_freeReg(tmp0100.regNro); - tmp0102 = riscv_genADD_3(tmp0102, In, tmp0101); - if (!tmp0102.dontFree) h2_freeReg(tmp0101.regNro); - tmp0103 = riscv_genR_3(tmp0103, tmp0102, immValueZero); - tmp0104 = riscv_genMUL_4(tmp0104, tmp0103, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+0]))}, immValueZero); - if (!tmp0104.dontFree) h2_freeReg(tmp0103.regNro); - sum = riscv_genADD_3(sum, sum, tmp0104); - if (!sum.dontFree) h2_freeReg(tmp0104.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0105 = riscv_genADD_3(tmp0105, stride, njm1); - tmp0106 = riscv_genMUL_4(tmp0106, tmp0105, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0106.dontFree) h2_freeReg(tmp0105.regNro); - tmp0107 = riscv_genADD_3(tmp0107, In, tmp0106); - if (!tmp0107.dontFree) h2_freeReg(tmp0106.regNro); - tmp0108 = riscv_genR_3(tmp0108, tmp0107, immValueZero); - tmp0109 = riscv_genMUL_4(tmp0109, tmp0108, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+1]))}, immValueZero); - if (!tmp0109.dontFree) h2_freeReg(tmp0108.regNro); - sum = riscv_genADD_3(sum, sum, tmp0109); - if (!sum.dontFree) h2_freeReg(tmp0109.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0110 = riscv_genADD_3(tmp0110, stride, column); - tmp0111 = riscv_genMUL_4(tmp0111, tmp0110, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0111.dontFree) h2_freeReg(tmp0110.regNro); - tmp0112 = riscv_genADD_3(tmp0112, In, tmp0111); - if (!tmp0112.dontFree) h2_freeReg(tmp0111.regNro); - tmp0113 = riscv_genR_3(tmp0113, tmp0112, immValueZero); - tmp0114 = riscv_genMUL_4(tmp0114, tmp0113, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+2]))}, immValueZero); - if (!tmp0114.dontFree) h2_freeReg(tmp0113.regNro); - sum = riscv_genADD_3(sum, sum, tmp0114); - if (!sum.dontFree) h2_freeReg(tmp0114.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0115 = riscv_genADD_3(tmp0115, stride, njp1); - tmp0116 = riscv_genMUL_4(tmp0116, tmp0115, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0116.dontFree) h2_freeReg(tmp0115.regNro); - tmp0117 = riscv_genADD_3(tmp0117, In, tmp0116); - if (!tmp0117.dontFree) h2_freeReg(tmp0116.regNro); - tmp0118 = riscv_genR_3(tmp0118, tmp0117, immValueZero); - tmp0119 = riscv_genMUL_4(tmp0119, tmp0118, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+3]))}, immValueZero); - if (!tmp0119.dontFree) h2_freeReg(tmp0118.regNro); - sum = riscv_genADD_3(sum, sum, tmp0119); - if (!sum.dontFree) h2_freeReg(tmp0119.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0120 = riscv_genADD_3(tmp0120, stride, njp2); - tmp0121 = riscv_genMUL_4(tmp0121, tmp0120, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - if (!tmp0121.dontFree) h2_freeReg(tmp0120.regNro); - tmp0122 = riscv_genADD_3(tmp0122, In, tmp0121); - if (!tmp0122.dontFree) h2_freeReg(tmp0121.regNro); - tmp0123 = riscv_genR_3(tmp0123, tmp0122, immValueZero); - tmp0124 = riscv_genMUL_4(tmp0124, tmp0123, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((Filter[4*5+4]))}, immValueZero); - if (!tmp0124.dontFree) h2_freeReg(tmp0123.regNro); - sum = riscv_genADD_3(sum, sum, tmp0124); - if (!sum.dontFree) h2_freeReg(tmp0124.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0125 = riscv_genDIV_4(tmp0125, sum, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((coeff))}, immValueZero); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, tmp0125); - if (!tmp0126.dontFree) h2_freeReg(tmp0125.regNro); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -#if 0 -#endif -} - -// Compute a stencil for 1 point -int kernelStatic(imgStruct_t *In, int l, int c, imgStruct_t *Filter, int coeff) -{ - int line, column, sum = 0; - int offset = (Filter->width)/2; - - for (line = 0; line < Filter->height; line++) - { - for (column = 0; column < Filter->width; column++) - { - int ni = (l + line) - offset; - int nj = (c + column) - offset; - sum += In->pixelsArray[ni*In->width+nj] * Filter->pixelsArray[line*Filter->width+column]; - } - } - return sum / coeff; -} - - -void convolutionStatic(imgStruct_t *In, imgStruct_t *Out, imgStruct_t *Filter, int coeff) -{ - int offset = Filter->width/2; - int result; - for (int line = offset; line < In->height - offset; line++) - { - for (int column = offset; column < In->width - offset; column++) - { - result = kernelStatic(In, line, column, Filter, coeff); - Out->pixelsArray[line*Out->width+column] = clamp(result); - } - } -} - -void convolutionH4(imgStruct_t* In, imgStruct_t *Out, imgStruct_t *Filter, pifc kernelHL) -{ - int offset = Filter->width/2; - int result; - for (int line = offset; line < In->height - offset; line++) - { - for (int column = offset; column < In->width - offset; column++) - { - result = kernelHL(In->pixelsArray, line, column, In->width); - Out->pixelsArray[line*Out->width+column] = clamp(result); - } - } -} - -int compareImages(imgStruct_t *staticImg, imgStruct_t *H4Img) -{ - int errors = 0; - for(int line = 0 ; line < staticImg->height ; line++) - { - for(int column = 0 ; column < staticImg->width ; column++) - { - if((staticImg->pixelsArray[line*staticImg->width+column] - H4Img->pixelsArray[line*H4Img->width+column]) != 0) - { - if (0 == errors) - { - printf("Alert : first difference at line %i column %i\n", line, column); - } - errors++; - } - } - } - return errors; -} - -int main(int argc, char *argv[]) -{ - int error, coeff, nXperiment = 20; - imgStruct_t *In, *OutH4, *OutStatic, *Filter; - char *filterImageName, *inputImageName; - if (argc < 5) - { - printf ("./Stencil \n"); - exit(-1); - } - - inputImageName = argv[1]; - filterImageName = argv[4]; - In = readPgmImage(inputImageName); - Filter = readPgmImage(filterImageName); - coeff = imgSum (Filter); -#ifdef VERBOSE - printf ("%s: coeff %d\n", filterImageName, coeff); - printImage (Filter, "Filter"); -#endif - assert (Filter->width == Filter->height); // Only square filters - OutStatic = createImage (In->height, In->width); - OutH4 = createImage (In->height, In->width); -#ifdef VERBOSE - printf ("after init\n"); - printImage(In, "In"); -#endif - ticks_t timeStatic = h2_getticks(); // Static convolution - for (int i = 0; i < nXperiment; i++) - { - convolutionStatic(In, OutStatic, Filter, coeff); - } - timeStatic = h2_getticks() - timeStatic; -#ifdef VERBOSE - printf ("after static\n"); - printImage(OutStatic, "Out"); -#endif - - pifc kernelHL = (pifc)h2_malloc(8192); - ticks_t timeCodeGen = h2_getticks(); - switch (Filter->width) - { - case 1 : kernelHL = genKernel1x1 (kernelHL, Filter->pixelsArray, coeff); break; - case 3 : kernelHL = genKernel3x3 (kernelHL, Filter->pixelsArray, coeff); break; - case 5 : kernelHL = genKernel5x5 (kernelHL, Filter->pixelsArray, coeff); break; - default: printf ("Unknown filter size\n"); exit(-1); - } - timeCodeGen = h2_getticks() - timeCodeGen; - -#ifdef VERBOSE - printf ("after codegen\n"); -#endif - - ticks_t timeH4 = h2_getticks(); // Compilette convolution - for (int i = 0; i < nXperiment; i++) - { - convolutionH4(In, OutH4, Filter, kernelHL); - } - timeH4 = h2_getticks() - timeH4; -#ifdef VERBOSE - printf ("after h2\n"); - printImage(OutH4, "Out H4"); -#endif - error = compareImages(OutH4, OutStatic); - printf("%s;%ix%i;%ix%i;%lld;%lld;%lld;%d;%d\n", - filterImageName, - Filter->width, Filter->height, In->width, In->height, - timeStatic/nXperiment, timeH4/nXperiment, - h2_codeGenTime, h2_insnGenerated, - error); - -#if VERBOSE - writePgmImage(OutStatic, argv[2]); - writePgmImage(OutH4, argv[3]); -#endif - - return (0 == error)?0:-1; -} diff --git a/Demos/VectorMatrix/VectorMatrix.aarch64 b/Demos/VectorMatrix/VectorMatrix.aarch64 deleted file mode 100755 index a5729cd05c96d172a4e5eae14fce4cb790f73491..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63912 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -void A64_RET__I_64_1(){ /* ret */ - aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - -#ifdef H2_DEBUG_INSN -printf("%p : A64_RET__I_64_1\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_8_8(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_8_8\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_8_16(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_16_8(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_16_4(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_16_4\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_32_1(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_SUB_RRI_I_32_1(int r0,int r1,int i0){ /* sub */ - aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_32_2(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_32_2\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_32_4(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_64_2(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_64_2\n", h2_asm_pc); -#endif -} -void A64_SUB_RRI_I_64_1(int r0,int r1,int i0){ /* sub */ - aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void A64_SUB_RRR_I_64_1(int r0,int r1,int r2){ /* sub */ - aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_SUB_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_MOV_RRR_I_8_8(int r0,int r1,int r2){ /* mv */ - aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RRR_I_8_8\n", h2_asm_pc); -#endif -} -void A64_MOV_RRR_I_16_8(int r0,int r1,int r2){ /* mv */ - aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void A64_MV_RR_I_32_4(int r0,int r1){ /* mv */ - aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MV_RR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_MOV_RR_I_32_1(int r0,int r1){ /* mv */ - aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_MOVI_RI_I_32_4(int r0,int i0){ /* mv */ - aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOVI_RI_I_32_4\n", h2_asm_pc); -#endif -} -void A64_MOVI_RI_I_32_2(int r0,int i0){ /* mv */ - aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOVI_RI_I_32_2\n", h2_asm_pc); -#endif -} -void A64_DUP_RR_I_32_4(int r0,int r1){ /* mv */ - aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_DUP_RR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_MOV_RI_I_32_1(int r0,int i0){ /* mv */ - aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_MOV_RR_I_32_2(int r0,int r1){ /* mv */ - aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RR_I_32_2\n", h2_asm_pc); -#endif -} -void A64_DUP_RR_I_32_1(int r0,int r1){ /* mv */ - aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_DUP_RR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_DUP_RR_I_32_2(int r0,int r1){ /* mv */ - aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_DUP_RR_I_32_2\n", h2_asm_pc); -#endif -} -void A64_MOV_RR_I_64_1(int r0,int r1){ /* mv */ - aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_MOV_RI_I_64_1(int r0,int i0){ /* mv */ - aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MOV_RI_I_64_1\n", h2_asm_pc); -#endif -} -void A64_DUP_RR_I_64_1(int r0,int r1){ /* mv */ - aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_DUP_RR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_DUP_RR_I_64_2(int r0,int r1){ /* mv */ - aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_DUP_RR_I_64_2\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_8_8(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_8_8\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_8_16(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_16_4(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_16_4\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_16_8(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_32_4(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_32_1(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_32_2(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_32_2\n", h2_asm_pc); -#endif -} -void A64_MUL_RRR_I_64_1(int r0,int r1,int r2){ /* mul */ - aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_MUL_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_8_8(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_8_8\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_8_16(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_16_8(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_16_4(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_16_4\n", h2_asm_pc); -#endif -} -void A64_ADD_RRI_I_32_1(int r0,int r1,int i0){ /* add */ - aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_32_1(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_32_2(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_32_2\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_32_4(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_64_2(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_64_2\n", h2_asm_pc); -#endif -} -void A64_ADD_RRR_I_64_1(int r0,int r1,int r2){ /* add */ - aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_ADD_RRI_I_64_1(int r0,int r1,int i0){ /* add */ - aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ADD_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void A64_LSR_RRI_I_32_1(int r0,int r1,int i0){ /* sr */ - aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSR_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_LSR_RRR_I_32_1(int r0,int r1,int r2){ /* sr */ - aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSR_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_LSR_RRI_I_64_1(int r0,int r1,int i0){ /* sr */ - aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSR_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void A64_LSR_RRR_I_64_1(int r0,int r1,int r2){ /* sr */ - aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSR_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_ST1_RR_I_8_8(int r0,int r1){ /* w */ - aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ST1_RR_I_8_8\n", h2_asm_pc); -#endif -} -void A64_ST1_RR_I_8_16(int r0,int r1){ /* w */ - aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ST1_RR_I_8_16\n", h2_asm_pc); -#endif -} -void A64_STRB_RRI_I_8_1(int r0,int r1,int i0){ /* w */ - aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STRB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void A64_ST1_RR_I_16_8(int r0,int r1){ /* w */ - aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ST1_RR_I_16_8\n", h2_asm_pc); -#endif -} -void A64_ST1_RR_I_16_4(int r0,int r1){ /* w */ - aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ST1_RR_I_16_4\n", h2_asm_pc); -#endif -} -void A64_STRH_RRI_I_16_1(int r0,int r1,int i0){ /* w */ - aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STRH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void A64_STR_RRR_I_32_1(int r0,int r1,int r2){ /* w */ - aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STR_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_STR_RRI_I_32_1(int r0,int r1,int i0){ /* w */ - aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STR_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_STR_RRI_I_32_2(int r0,int r1,int i0){ /* w */ - aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STR_RRI_I_32_2\n", h2_asm_pc); -#endif -} -void A64_ST1_RR_I_32_4(int r0,int r1){ /* w */ - aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ST1_RR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_STR_RRR_I_64_1(int r0,int r1,int r2){ /* w */ - aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STR_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_ST1_RR_I_64_2(int r0,int r1){ /* w */ - aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_ST1_RR_I_64_2\n", h2_asm_pc); -#endif -} -void A64_STR_RRI_I_64_1(int r0,int r1,int i0){ /* w */ - aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_STR_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_8_16(int r0,int r1){ /* r */ - aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_8_16\n", h2_asm_pc); -#endif -} -void A64_LDRB_RRI_I_8_1(int r0,int r1,int i0){ /* r */ - aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LDRB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_8_8(int r0,int r1){ /* r */ - aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_8_8\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_16_4(int r0,int r1){ /* r */ - aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_16_4\n", h2_asm_pc); -#endif -} -void A64_LDRH_RRI_I_16_1(int r0,int r1,int i0){ /* r */ - aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LDRH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_16_8(int r0,int r1){ /* r */ - aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_16_8\n", h2_asm_pc); -#endif -} -void A64_LDR_RRI_I_32_1(int r0,int r1,int i0){ /* r */ - aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LDR_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_LDP_RRI_I_32_2(int r0,int r1,int i0){ /* r */ - aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LDP_RRI_I_32_2\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_32_2(int r0,int r1){ /* r */ - aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_32_2\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_32_4(int r0,int r1){ /* r */ - aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_32_4\n", h2_asm_pc); -#endif -} -void A64_LDR_RRR_I_64_1(int r0,int r1,int r2){ /* r */ - aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LDR_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void A64_LD1_RR_I_64_2(int r0,int r1){ /* r */ - aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LD1_RR_I_64_2\n", h2_asm_pc); -#endif -} -void A64_LSL_RRI_I_32_1(int r0,int r1,int i0){ /* sl */ - aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSL_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void A64_LSL_RRR_I_32_1(int r0,int r1,int r2){ /* sl */ - aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void A64_LSL_RRI_I_64_1(int r0,int r1,int i0){ /* sl */ - aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSL_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void A64_LSL_RRR_I_64_1(int r0,int r1,int r2){ /* sl */ - aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : A64_LSL_RRR_I_64_1\n", h2_asm_pc); -#endif -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -/* -*- c -*- */ -// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/mesa/math/m_matrix.c -#include -#include -#include -#include -#define T 4 -typedef int d_t; -typedef d_t matrix_t [T][T]; -typedef d_t vector_t [T]; -typedef d_t (*pifvv)(vector_t, vector_t); - -pifvv genVectorMatrixProduct(pifvv ptr, matrix_t m) -{ - /* Code Generation of 5 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t o = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0103, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = aarch64_genMUL_3(tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0001 = aarch64_genADD_3(tmp0001, o, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = aarch64_genMUL_3(tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0003 = aarch64_genADD_3(tmp0003, i, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = aarch64_genR_3(tmp0004, tmp0003, immValueZero); - tmp0005 = aarch64_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][0]))}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = aarch64_genMUL_3(tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0007 = aarch64_genADD_3(tmp0007, i, tmp0006); - if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); - tmp0008 = aarch64_genR_3(tmp0008, tmp0007, immValueZero); - tmp0009 = aarch64_genMUL_3(tmp0009, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][0]))}); - if (!tmp0009.dontFree) h2_freeReg(tmp0008.regNro); - tmp0010 = aarch64_genADD_3(tmp0010, tmp0005, tmp0009); - if (!tmp0010.dontFree) h2_freeReg(tmp0005.regNro); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = aarch64_genMUL_3(tmp0011, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0012 = aarch64_genADD_3(tmp0012, i, tmp0011); - if (!tmp0012.dontFree) h2_freeReg(tmp0011.regNro); - tmp0013 = aarch64_genR_3(tmp0013, tmp0012, immValueZero); - tmp0014 = aarch64_genMUL_3(tmp0014, tmp0013, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][0]))}); - if (!tmp0014.dontFree) h2_freeReg(tmp0013.regNro); - tmp0015 = aarch64_genADD_3(tmp0015, tmp0010, tmp0014); - if (!tmp0015.dontFree) h2_freeReg(tmp0010.regNro); - if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); - tmp0016 = aarch64_genMUL_3(tmp0016, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0017 = aarch64_genADD_3(tmp0017, i, tmp0016); - if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); - tmp0018 = aarch64_genR_3(tmp0018, tmp0017, immValueZero); - tmp0019 = aarch64_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][0]))}); - if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); - tmp0020 = aarch64_genADD_3(tmp0020, tmp0015, tmp0019); - if (!tmp0020.dontFree) h2_freeReg(tmp0015.regNro); - if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); - aarch64_genW_3(tmp0001, tmp0020, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0021 = aarch64_genMUL_3(tmp0021, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0022 = aarch64_genADD_3(tmp0022, o, tmp0021); - if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); - tmp0023 = aarch64_genMUL_3(tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0024 = aarch64_genADD_3(tmp0024, i, tmp0023); - if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); - tmp0025 = aarch64_genR_3(tmp0025, tmp0024, immValueZero); - tmp0026 = aarch64_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][1]))}); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = aarch64_genMUL_3(tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0028 = aarch64_genADD_3(tmp0028, i, tmp0027); - if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); - tmp0029 = aarch64_genR_3(tmp0029, tmp0028, immValueZero); - tmp0030 = aarch64_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][1]))}); - if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); - tmp0031 = aarch64_genADD_3(tmp0031, tmp0026, tmp0030); - if (!tmp0031.dontFree) h2_freeReg(tmp0026.regNro); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = aarch64_genMUL_3(tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0033 = aarch64_genADD_3(tmp0033, i, tmp0032); - if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); - tmp0034 = aarch64_genR_3(tmp0034, tmp0033, immValueZero); - tmp0035 = aarch64_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][1]))}); - if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); - tmp0036 = aarch64_genADD_3(tmp0036, tmp0031, tmp0035); - if (!tmp0036.dontFree) h2_freeReg(tmp0031.regNro); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = aarch64_genMUL_3(tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0038 = aarch64_genADD_3(tmp0038, i, tmp0037); - if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); - tmp0039 = aarch64_genR_3(tmp0039, tmp0038, immValueZero); - tmp0040 = aarch64_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][1]))}); - if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); - tmp0041 = aarch64_genADD_3(tmp0041, tmp0036, tmp0040); - if (!tmp0041.dontFree) h2_freeReg(tmp0036.regNro); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - aarch64_genW_3(tmp0022, tmp0041, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0042 = aarch64_genMUL_3(tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0043 = aarch64_genADD_3(tmp0043, o, tmp0042); - if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); - tmp0044 = aarch64_genMUL_3(tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0045 = aarch64_genADD_3(tmp0045, i, tmp0044); - if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); - tmp0046 = aarch64_genR_3(tmp0046, tmp0045, immValueZero); - tmp0047 = aarch64_genMUL_3(tmp0047, tmp0046, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][2]))}); - if (!tmp0047.dontFree) h2_freeReg(tmp0046.regNro); - tmp0048 = aarch64_genMUL_3(tmp0048, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0049 = aarch64_genADD_3(tmp0049, i, tmp0048); - if (!tmp0049.dontFree) h2_freeReg(tmp0048.regNro); - tmp0050 = aarch64_genR_3(tmp0050, tmp0049, immValueZero); - tmp0051 = aarch64_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][2]))}); - if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); - tmp0052 = aarch64_genADD_3(tmp0052, tmp0047, tmp0051); - if (!tmp0052.dontFree) h2_freeReg(tmp0047.regNro); - if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); - tmp0053 = aarch64_genMUL_3(tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0054 = aarch64_genADD_3(tmp0054, i, tmp0053); - if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); - tmp0055 = aarch64_genR_3(tmp0055, tmp0054, immValueZero); - tmp0056 = aarch64_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][2]))}); - if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); - tmp0057 = aarch64_genADD_3(tmp0057, tmp0052, tmp0056); - if (!tmp0057.dontFree) h2_freeReg(tmp0052.regNro); - if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); - tmp0058 = aarch64_genMUL_3(tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0059 = aarch64_genADD_3(tmp0059, i, tmp0058); - if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); - tmp0060 = aarch64_genR_3(tmp0060, tmp0059, immValueZero); - tmp0061 = aarch64_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][2]))}); - if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); - tmp0062 = aarch64_genADD_3(tmp0062, tmp0057, tmp0061); - if (!tmp0062.dontFree) h2_freeReg(tmp0057.regNro); - if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); - aarch64_genW_3(tmp0043, tmp0062, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0063 = aarch64_genMUL_3(tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0064 = aarch64_genADD_3(tmp0064, o, tmp0063); - if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); - tmp0065 = aarch64_genMUL_3(tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0066 = aarch64_genADD_3(tmp0066, i, tmp0065); - if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); - tmp0067 = aarch64_genR_3(tmp0067, tmp0066, immValueZero); - tmp0068 = aarch64_genMUL_3(tmp0068, tmp0067, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][3]))}); - if (!tmp0068.dontFree) h2_freeReg(tmp0067.regNro); - tmp0069 = aarch64_genMUL_3(tmp0069, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0070 = aarch64_genADD_3(tmp0070, i, tmp0069); - if (!tmp0070.dontFree) h2_freeReg(tmp0069.regNro); - tmp0071 = aarch64_genR_3(tmp0071, tmp0070, immValueZero); - tmp0072 = aarch64_genMUL_3(tmp0072, tmp0071, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][3]))}); - if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); - tmp0073 = aarch64_genADD_3(tmp0073, tmp0068, tmp0072); - if (!tmp0073.dontFree) h2_freeReg(tmp0068.regNro); - if (!tmp0073.dontFree) h2_freeReg(tmp0072.regNro); - tmp0074 = aarch64_genMUL_3(tmp0074, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0075 = aarch64_genADD_3(tmp0075, i, tmp0074); - if (!tmp0075.dontFree) h2_freeReg(tmp0074.regNro); - tmp0076 = aarch64_genR_3(tmp0076, tmp0075, immValueZero); - tmp0077 = aarch64_genMUL_3(tmp0077, tmp0076, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][3]))}); - if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); - tmp0078 = aarch64_genADD_3(tmp0078, tmp0073, tmp0077); - if (!tmp0078.dontFree) h2_freeReg(tmp0073.regNro); - if (!tmp0078.dontFree) h2_freeReg(tmp0077.regNro); - tmp0079 = aarch64_genMUL_3(tmp0079, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0080 = aarch64_genADD_3(tmp0080, i, tmp0079); - if (!tmp0080.dontFree) h2_freeReg(tmp0079.regNro); - tmp0081 = aarch64_genR_3(tmp0081, tmp0080, immValueZero); - tmp0082 = aarch64_genMUL_3(tmp0082, tmp0081, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][3]))}); - if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); - tmp0083 = aarch64_genADD_3(tmp0083, tmp0078, tmp0082); - if (!tmp0083.dontFree) h2_freeReg(tmp0078.regNro); - if (!tmp0083.dontFree) h2_freeReg(tmp0082.regNro); - aarch64_genW_3(tmp0064, tmp0083, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -d_t VectorMatrixProductUnrolled (vector_t o, vector_t i, matrix_t m) -{ - o[0] = i[0]*m[0][0] + i[1]*m[1][0] + i[2]*m[2][0] + i[3]*m[3][0]; - o[1] = i[0]*m[0][1] + i[1]*m[1][1] + i[2]*m[2][1] + i[3]*m[3][1]; - o[2] = i[0]*m[0][2] + i[1]*m[1][2] + i[2]*m[2][2] + i[3]*m[3][2]; - o[3] = i[0]*m[0][3] + i[1]*m[1][3] + i[2]*m[2][3] + i[3]*m[3][3]; - return o[3]; -} - -#if 0 // What the binary code should be with a translation matrix -d_t VectorMatrixProductUnrolledSR(vector_t o, vector_t i, matrix_t m) -{ - - o[0] = m[0][0] * i[0] + + m[3][0] * i[3]; - o[1] = m[1][1] * i[1] + + m[3][1] * i[3]; - o[2] = m[2][2] * i[2] + m[3][2] * i[3]; - o[3] = + i[3]; - return o[3]; -} -#endif -d_t VectorMatrixProduct (vector_t o, vector_t i, matrix_t m) -{ - for (int column = 0; column < T; column++) - { - o[column] = 0; - for (int line = 0; line < T; line++) - { - o[column] += i[line] * m[line][column]; - - } - } - return o[3]; -} - - -int VectorMatrixProductCount(matrix_t mat) -{ - int op = 0; - for (int column = 0; column < T; column++) - { - for (int line = 0; line < T; line++) - { - switch (mat[line][column]) - { - case 0 : op += 0; break; - case 1 : op += 1; break; - default: op += 2; break; - } - } - } - return op; -} - - -void printMatrix (matrix_t m, char msg[]) -{ - printf ("%s:\n", msg); - for (int column = 0; column < T; column++) - { - for (int line = 0; line < T; line++) - { - printf ("%4d ", m[line][column]); - } - printf ("\n"); - } - printf ("\n"); -} - -void printVector (vector_t v, char msg[]) -{ - for (int i = 0; i < T; i++) - printf ("%4d ", v[i]); - printf ("%s\n", msg); -} - -bool vectorCompare(vector_t ref[], vector_t other[], char * msg, int doPrint, int nVector) -{ - int has_differences = false; - for (int line = 0; line < nVector; line++) - for (int i = 0; i < T; i++) - { - if (ref[line][i] != other[line][i]) - has_differences = true; - if (doPrint) - printf("%4d ", other[line][i]); - } - /* printf("%s : ", msg); */ - /* printf(" %s\n", (has_differences)?"NOT OK":"OK"); */ - return has_differences; -} - -int main (int argc, char *argv[]) -{ - matrix_t m; - char *matrixName; - // vector_t in0 = {1, 2, 3, 4}, in1 = {5, 6, 7, 8}; - vector_t *out, *cout, *in; - uint64_t timeGeneral, timeCompilette; - pifvv vmProduct; - int tmp, doPrint, nXperiment; - unsigned long acc; - bool resultValid; - - if (argc != 19) - { - printf ("Not enough arguments %d\n", argc); - printf ("VectorMatrix ExperimentNumber MatrixName M11 M12 ... M44\n"); - exit (-1); - } - doPrint = 0; - acc = 0; - nXperiment = atoi (argv[1]); - matrixName = argv[2]; - for (int line = 0; line < 4; line++) - for (int column = 0; column < 4; column++) - { - m[line][column] = atoi (argv[3 + line*4+column]); - } -#ifdef VERBOSE - printMatrix(m, matrixName); -#endif - - in = calloc(nXperiment, sizeof (vector_t)); - out = calloc(nXperiment, sizeof (vector_t)); - cout = calloc(nXperiment, sizeof (vector_t)); - - for (int line = 0; line < nXperiment; line++) - for (int column = 0; column < 4; column++) - in[line][column] = random () % 1000; - - tmp = VectorMatrixProductCount (m); - printf("Operation count Matrix %s : %d theoretical speedup %.1f\n", matrixName, tmp, (0==tmp)?32:32.0/tmp); - -// Repeat one instruction and count ticks -#define DO(INSN, REPEAT, TIME) {uint64_t tickCount = h2_getticks();for (int i = 0; i < REPEAT; i++) INSN; TIME = h2_getticks() - tickCount;} - -#ifdef VERBOSE - printVector (in[0], "Input vector #0"); -#endif - - acc += VectorMatrixProduct (out[0], in[0], m); /* Cold start */ - DO(acc += VectorMatrixProduct (out[i], in[i], m), nXperiment, timeGeneral) - -#ifdef VERBOSE - printVector (out[0], "Output vector #0 (general)"); -#endif - -#if 0 // Possible test with a source level unrolled version - uint64_t timeUnrolled; - vector_t uout0, uout1; - acc += VectorMatrixProductUnrolled (uout0, in0, m); - DO(acc += VectorMatrixProductUnrolled (uout1, in1, m), nXperiment, timeUnrolled); - vectorCompare(out1, uout1, "Unrolled out0", doPrint); -#endif - - vmProduct = (pifvv) h2_malloc(1024); - vmProduct = genVectorMatrixProduct (vmProduct, m); - acc += vmProduct (cout[0], in[0]); - DO(acc += vmProduct (cout[i], in[i]), nXperiment, timeCompilette); - -#ifdef VERBOSE - printVector (cout[0], "Output vector #0 (compilette)"); -#endif - - resultValid = vectorCompare(out, cout, "Compilette", doPrint, nXperiment); - - printf ("%s;%d;%lu;%lu;%lld;%d;%s\n", - matrixName, nXperiment, - timeGeneral, timeCompilette, - h2_codeGenTime, h2_insnGenerated, - resultValid?"true":"false"); - return resultValid; -} diff --git a/Demos/VectorMatrix/VectorMatrix.power b/Demos/VectorMatrix/VectorMatrix.power deleted file mode 100755 index 3cf332b703c4aebb261c30c4221ad8674f510874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80624 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 XKfZptzwnlb`R^@Q%BvoO*9`szd0{3w diff --git a/Demos/VectorMatrix/VectorMatrix.power.c b/Demos/VectorMatrix/VectorMatrix.power.c deleted file mode 100644 index ef2ed96..0000000 --- a/Demos/VectorMatrix/VectorMatrix.power.c +++ /dev/null @@ -1,1457 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -void P1_BLR__I_32_1(){ /* ret */ - power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - -#ifdef H2_DEBUG_INSN -printf("%p : P1_BLR__I_32_1\n", h2_asm_pc); -#endif -} -void P1_SUBI_RRI_I_32_1(int r0,int r1,int i0){ /* sub */ - power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_SUBI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void PPC_SUB_RRR_I_32_1(int r0,int r2,int r1){ /* sub */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : PPC_SUB_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void P1_LI_RI_I_32_1(int r0,int i0){ /* mv */ - power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LI_RI_I_32_1\n", h2_asm_pc); -#endif -} -void P1_MV_RR_I_32_1(int r0,int r1){ /* mv */ - power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_MV_RR_I_32_1\n", h2_asm_pc); -#endif -} -void P1_LI_RI_I_64_1(int r0,int i0){ /* mv */ - power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LI_RI_I_64_1\n", h2_asm_pc); -#endif -} -void V2_03_VSRB_RRR_I_8_16(int r0,int r1,int r2){ /* sr */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSRB_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void V2_03_VSRH_RRR_I_16_8(int r0,int r1,int r2){ /* sr */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSRH_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void V2_03_VSRW_RRR_I_32_4(int r0,int r1,int r2){ /* sr */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSRW_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void V2_07_VSRD_RRR_I_64_2(int r0,int r1,int r2){ /* sr */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_07_VSRD_RRR_I_64_2\n", h2_asm_pc); -#endif -} -void V2_03_VSR_RRR_I_128_1(int r0,int r1,int r2){ /* sr */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSR_RRR_I_128_1\n", h2_asm_pc); -#endif -} -void P1_MULLW_RRR_I_32_1(int r0,int r1,int r2){ /* mul */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_MULLW_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void P1_MULLI_RRI_I_64_1(int r0,int r1,int i0){ /* mul */ - power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_MULLI_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void V2_03_VADDSBS_RRR_I_8_16(int r0,int r1,int r2){ /* add */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VADDSBS_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void V2_03_VADDUBS_RRR_I_8_16(int r0,int r1,int r2){ /* add */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VADDUBS_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void V2_03_VADDSHS_RRR_I_16_8(int r0,int r1,int r2){ /* add */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VADDSHS_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void V2_03_VADDUHS_RRR_I_16_8(int r0,int r1,int r2){ /* add */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VADDUHS_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void V2_03_VADDUWS_RRR_I_32_4(int r0,int r1,int r2){ /* add */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VADDUWS_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void P1_ADDI_RRI_I_32_1(int r0,int r1,int i0){ /* add */ - power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_ADDI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void V2_03_VADDSWS_RRR_I_32_4(int r0,int r1,int r2){ /* add */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VADDSWS_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void P1_ADD_RRR_I_32_1(int r0,int r1,int r2){ /* add */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_ADD_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void P1_ADD_RRR_I_64_1(int r0,int r1,int r2){ /* add */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_ADD_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void P1_ADDI_RRI_I_64_1(int r0,int r1,int i0){ /* add */ - power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_ADDI_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void P1_STB_RRI_I_8_1(int r1,int r0,int i0){ /* w */ - power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_STB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void P1_STBX_RRR_I_8_1(int r1,int r0,int r2){ /* w */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_STBX_RRR_I_8_1\n", h2_asm_pc); -#endif -} -void P1_STH_RRI_I_16_1(int r1,int r0,int i0){ /* w */ - power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_STH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void P1_STW_RRI_I_32_1(int r1,int r0,int i0){ /* w */ - power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_STW_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void P1_STWX_RRR_I_32_1(int r0,int r1,int r2){ /* w */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_STWX_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void PPC_STD_RRI_I_64_1(int r1,int r0,int i0){ /* w */ - power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : PPC_STD_RRI_I_64_1\n", h2_asm_pc); -#endif -} -void P1_LBZ_RRI_I_8_1(int r0,int r1,int i0){ /* r */ - power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LBZ_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void P1_LBZX_RRR_I_8_1(int r0,int r1,int r2){ /* r */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LBZX_RRR_I_8_1\n", h2_asm_pc); -#endif -} -void P1_LHZ_RRI_I_16_1(int r0,int r1,int i0){ /* r */ - power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LHZ_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void P1_LWZ_RRI_I_32_1(int r0,int r1,int i0){ /* r */ - power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LWZ_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void P1_LWZU_RRI_I_32_1(int r0,int r1,int i0){ /* r */ - power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LWZU_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void P1_LWZUX_RRR_I_32_1(int r0,int r1,int r2){ /* r */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LWZUX_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void P1_LWZX_RRR_I_32_1(int r0,int r1,int r2){ /* r */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_LWZX_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void V2_03_VSLB_RRR_I_8_16(int r0,int r1,int r2){ /* sl */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSLB_RRR_I_8_16\n", h2_asm_pc); -#endif -} -void V2_03_VSLH_RRR_I_16_8(int r0,int r1,int r2){ /* sl */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSLH_RRR_I_16_8\n", h2_asm_pc); -#endif -} -void P1_SLW_RRR_I_32_1(int r1,int r0,int r2){ /* sl */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_SLW_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void P1_SLW__RRR_I_32_1(int r1,int r0,int r2){ /* sl */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : P1_SLW__RRR_I_32_1\n", h2_asm_pc); -#endif -} -void V2_03_VSLW_RRR_I_32_4(int r0,int r1,int r2){ /* sl */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSLW_RRR_I_32_4\n", h2_asm_pc); -#endif -} -void PPC_SLD_RRR_I_64_1(int r1,int r0,int r2){ /* sl */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : PPC_SLD_RRR_I_64_1\n", h2_asm_pc); -#endif -} -void PPC_SLD__RRR_I_64_1(int r1,int r0,int r2){ /* sl */ - power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : PPC_SLD__RRR_I_64_1\n", h2_asm_pc); -#endif -} -void V2_07_VSLD_RRR_I_64_2(int r0,int r1,int r2){ /* sl */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_07_VSLD_RRR_I_64_2\n", h2_asm_pc); -#endif -} -void V2_03_VSL_RRR_I_128_1(int r0,int r1,int r2){ /* sl */ - power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : V2_03_VSL_RRR_I_128_1\n", h2_asm_pc); -#endif -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} - -/* End Header autogenerated part */ -/* -*- c -*- */ -// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/mesa/math/m_matrix.c -#include -#include -#include -#include -#define T 4 -typedef int d_t; -typedef d_t matrix_t [T][T]; -typedef d_t vector_t [T]; -typedef d_t (*pifvv)(vector_t, vector_t); - -pifvv genVectorMatrixProduct(pifvv ptr, matrix_t m) -{ - /* Code Generation of 5 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t o = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 4, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 64, -1, false}; - h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x381F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp0000 = power_genMUL_3(tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0001 = power_genADD_3(tmp0001, o, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = power_genMUL_3(tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0003 = power_genADD_3(tmp0003, i, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = power_genR_3(tmp0004, tmp0003, immValueZero); - tmp0005 = power_genMUL_3(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][0]))}); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = power_genMUL_3(tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0007 = power_genADD_3(tmp0007, i, tmp0006); - if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); - tmp0008 = power_genR_3(tmp0008, tmp0007, immValueZero); - tmp0009 = power_genMUL_3(tmp0009, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][0]))}); - if (!tmp0009.dontFree) h2_freeReg(tmp0008.regNro); - tmp0010 = power_genADD_3(tmp0010, tmp0005, tmp0009); - if (!tmp0010.dontFree) h2_freeReg(tmp0005.regNro); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = power_genMUL_3(tmp0011, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0012 = power_genADD_3(tmp0012, i, tmp0011); - if (!tmp0012.dontFree) h2_freeReg(tmp0011.regNro); - tmp0013 = power_genR_3(tmp0013, tmp0012, immValueZero); - tmp0014 = power_genMUL_3(tmp0014, tmp0013, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][0]))}); - if (!tmp0014.dontFree) h2_freeReg(tmp0013.regNro); - tmp0015 = power_genADD_3(tmp0015, tmp0010, tmp0014); - if (!tmp0015.dontFree) h2_freeReg(tmp0010.regNro); - if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); - tmp0016 = power_genMUL_3(tmp0016, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0017 = power_genADD_3(tmp0017, i, tmp0016); - if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); - tmp0018 = power_genR_3(tmp0018, tmp0017, immValueZero); - tmp0019 = power_genMUL_3(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][0]))}); - if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); - tmp0020 = power_genADD_3(tmp0020, tmp0015, tmp0019); - if (!tmp0020.dontFree) h2_freeReg(tmp0015.regNro); - if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); - power_genW_3(tmp0001, tmp0020, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0021 = power_genMUL_3(tmp0021, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0022 = power_genADD_3(tmp0022, o, tmp0021); - if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); - tmp0023 = power_genMUL_3(tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0024 = power_genADD_3(tmp0024, i, tmp0023); - if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); - tmp0025 = power_genR_3(tmp0025, tmp0024, immValueZero); - tmp0026 = power_genMUL_3(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][1]))}); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = power_genMUL_3(tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0028 = power_genADD_3(tmp0028, i, tmp0027); - if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); - tmp0029 = power_genR_3(tmp0029, tmp0028, immValueZero); - tmp0030 = power_genMUL_3(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][1]))}); - if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); - tmp0031 = power_genADD_3(tmp0031, tmp0026, tmp0030); - if (!tmp0031.dontFree) h2_freeReg(tmp0026.regNro); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = power_genMUL_3(tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0033 = power_genADD_3(tmp0033, i, tmp0032); - if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); - tmp0034 = power_genR_3(tmp0034, tmp0033, immValueZero); - tmp0035 = power_genMUL_3(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][1]))}); - if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); - tmp0036 = power_genADD_3(tmp0036, tmp0031, tmp0035); - if (!tmp0036.dontFree) h2_freeReg(tmp0031.regNro); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = power_genMUL_3(tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0038 = power_genADD_3(tmp0038, i, tmp0037); - if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); - tmp0039 = power_genR_3(tmp0039, tmp0038, immValueZero); - tmp0040 = power_genMUL_3(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][1]))}); - if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); - tmp0041 = power_genADD_3(tmp0041, tmp0036, tmp0040); - if (!tmp0041.dontFree) h2_freeReg(tmp0036.regNro); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - power_genW_3(tmp0022, tmp0041, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0042 = power_genMUL_3(tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0043 = power_genADD_3(tmp0043, o, tmp0042); - if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); - tmp0044 = power_genMUL_3(tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0045 = power_genADD_3(tmp0045, i, tmp0044); - if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); - tmp0046 = power_genR_3(tmp0046, tmp0045, immValueZero); - tmp0047 = power_genMUL_3(tmp0047, tmp0046, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][2]))}); - if (!tmp0047.dontFree) h2_freeReg(tmp0046.regNro); - tmp0048 = power_genMUL_3(tmp0048, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0049 = power_genADD_3(tmp0049, i, tmp0048); - if (!tmp0049.dontFree) h2_freeReg(tmp0048.regNro); - tmp0050 = power_genR_3(tmp0050, tmp0049, immValueZero); - tmp0051 = power_genMUL_3(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][2]))}); - if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); - tmp0052 = power_genADD_3(tmp0052, tmp0047, tmp0051); - if (!tmp0052.dontFree) h2_freeReg(tmp0047.regNro); - if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); - tmp0053 = power_genMUL_3(tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0054 = power_genADD_3(tmp0054, i, tmp0053); - if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); - tmp0055 = power_genR_3(tmp0055, tmp0054, immValueZero); - tmp0056 = power_genMUL_3(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][2]))}); - if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); - tmp0057 = power_genADD_3(tmp0057, tmp0052, tmp0056); - if (!tmp0057.dontFree) h2_freeReg(tmp0052.regNro); - if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); - tmp0058 = power_genMUL_3(tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0059 = power_genADD_3(tmp0059, i, tmp0058); - if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); - tmp0060 = power_genR_3(tmp0060, tmp0059, immValueZero); - tmp0061 = power_genMUL_3(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][2]))}); - if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); - tmp0062 = power_genADD_3(tmp0062, tmp0057, tmp0061); - if (!tmp0062.dontFree) h2_freeReg(tmp0057.regNro); - if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); - power_genW_3(tmp0043, tmp0062, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0063 = power_genMUL_3(tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0064 = power_genADD_3(tmp0064, o, tmp0063); - if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); - tmp0065 = power_genMUL_3(tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0066 = power_genADD_3(tmp0066, i, tmp0065); - if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); - tmp0067 = power_genR_3(tmp0067, tmp0066, immValueZero); - tmp0068 = power_genMUL_3(tmp0068, tmp0067, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][3]))}); - if (!tmp0068.dontFree) h2_freeReg(tmp0067.regNro); - tmp0069 = power_genMUL_3(tmp0069, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0070 = power_genADD_3(tmp0070, i, tmp0069); - if (!tmp0070.dontFree) h2_freeReg(tmp0069.regNro); - tmp0071 = power_genR_3(tmp0071, tmp0070, immValueZero); - tmp0072 = power_genMUL_3(tmp0072, tmp0071, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][3]))}); - if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); - tmp0073 = power_genADD_3(tmp0073, tmp0068, tmp0072); - if (!tmp0073.dontFree) h2_freeReg(tmp0068.regNro); - if (!tmp0073.dontFree) h2_freeReg(tmp0072.regNro); - tmp0074 = power_genMUL_3(tmp0074, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0075 = power_genADD_3(tmp0075, i, tmp0074); - if (!tmp0075.dontFree) h2_freeReg(tmp0074.regNro); - tmp0076 = power_genR_3(tmp0076, tmp0075, immValueZero); - tmp0077 = power_genMUL_3(tmp0077, tmp0076, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][3]))}); - if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); - tmp0078 = power_genADD_3(tmp0078, tmp0073, tmp0077); - if (!tmp0078.dontFree) h2_freeReg(tmp0073.regNro); - if (!tmp0078.dontFree) h2_freeReg(tmp0077.regNro); - tmp0079 = power_genMUL_3(tmp0079, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 64, 0, (int)((1 * 32) / 8)}); - tmp0080 = power_genADD_3(tmp0080, i, tmp0079); - if (!tmp0080.dontFree) h2_freeReg(tmp0079.regNro); - tmp0081 = power_genR_3(tmp0081, tmp0080, immValueZero); - tmp0082 = power_genMUL_3(tmp0082, tmp0081, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][3]))}); - if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); - tmp0083 = power_genADD_3(tmp0083, tmp0078, tmp0082); - if (!tmp0083.dontFree) h2_freeReg(tmp0078.regNro); - if (!tmp0083.dontFree) h2_freeReg(tmp0082.regNro); - power_genW_3(tmp0064, tmp0083, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -d_t VectorMatrixProductUnrolled (vector_t o, vector_t i, matrix_t m) -{ - o[0] = i[0]*m[0][0] + i[1]*m[1][0] + i[2]*m[2][0] + i[3]*m[3][0]; - o[1] = i[0]*m[0][1] + i[1]*m[1][1] + i[2]*m[2][1] + i[3]*m[3][1]; - o[2] = i[0]*m[0][2] + i[1]*m[1][2] + i[2]*m[2][2] + i[3]*m[3][2]; - o[3] = i[0]*m[0][3] + i[1]*m[1][3] + i[2]*m[2][3] + i[3]*m[3][3]; - return o[3]; -} - -#if 0 // What the binary code should be with a translation matrix -d_t VectorMatrixProductUnrolledSR(vector_t o, vector_t i, matrix_t m) -{ - - o[0] = m[0][0] * i[0] + + m[3][0] * i[3]; - o[1] = m[1][1] * i[1] + + m[3][1] * i[3]; - o[2] = m[2][2] * i[2] + m[3][2] * i[3]; - o[3] = + i[3]; - return o[3]; -} -#endif -d_t VectorMatrixProduct (vector_t o, vector_t i, matrix_t m) -{ - for (int column = 0; column < T; column++) - { - o[column] = 0; - for (int line = 0; line < T; line++) - { - o[column] += i[line] * m[line][column]; - - } - } - return o[3]; -} - - -int VectorMatrixProductCount(matrix_t mat) -{ - int op = 0; - for (int column = 0; column < T; column++) - { - for (int line = 0; line < T; line++) - { - switch (mat[line][column]) - { - case 0 : op += 0; break; - case 1 : op += 1; break; - default: op += 2; break; - } - } - } - return op; -} - - -void printMatrix (matrix_t m, char msg[]) -{ - printf ("%s:\n", msg); - for (int column = 0; column < T; column++) - { - for (int line = 0; line < T; line++) - { - printf ("%4d ", m[line][column]); - } - printf ("\n"); - } - printf ("\n"); -} - -void printVector (vector_t v, char msg[]) -{ - for (int i = 0; i < T; i++) - printf ("%4d ", v[i]); - printf ("%s\n", msg); -} - -bool vectorCompare(vector_t ref[], vector_t other[], char * msg, int doPrint, int nVector) -{ - int has_differences = false; - for (int line = 0; line < nVector; line++) - for (int i = 0; i < T; i++) - { - if (ref[line][i] != other[line][i]) - has_differences = true; - if (doPrint) - printf("%4d ", other[line][i]); - } - /* printf("%s : ", msg); */ - /* printf(" %s\n", (has_differences)?"NOT OK":"OK"); */ - return has_differences; -} - -int main (int argc, char *argv[]) -{ - matrix_t m; - char *matrixName; - // vector_t in0 = {1, 2, 3, 4}, in1 = {5, 6, 7, 8}; - vector_t *out, *cout, *in; - uint64_t timeGeneral, timeCompilette; - pifvv vmProduct; - int tmp, doPrint, nXperiment; - unsigned long acc; - bool resultValid; - - if (argc != 19) - { - printf ("Not enough arguments %d\n", argc); - printf ("VectorMatrix ExperimentNumber MatrixName M11 M12 ... M44\n"); - exit (-1); - } - doPrint = 0; - acc = 0; - nXperiment = atoi (argv[1]); - matrixName = argv[2]; - for (int line = 0; line < 4; line++) - for (int column = 0; column < 4; column++) - { - m[line][column] = atoi (argv[3 + line*4+column]); - } -#ifdef VERBOSE - printMatrix(m, matrixName); -#endif - - in = calloc(nXperiment, sizeof (vector_t)); - out = calloc(nXperiment, sizeof (vector_t)); - cout = calloc(nXperiment, sizeof (vector_t)); - - for (int line = 0; line < nXperiment; line++) - for (int column = 0; column < 4; column++) - in[line][column] = random () % 1000; - - tmp = VectorMatrixProductCount (m); - printf("Operation count Matrix %s : %d theoretical speedup %.1f\n", matrixName, tmp, (0==tmp)?32:32.0/tmp); - -// Repeat one instruction and count ticks -#define DO(INSN, REPEAT, TIME) {uint64_t tickCount = h2_getticks();for (int i = 0; i < REPEAT; i++) INSN; TIME = h2_getticks() - tickCount;} - -#ifdef VERBOSE - printVector (in[0], "Input vector #0"); -#endif - - acc += VectorMatrixProduct (out[0], in[0], m); /* Cold start */ - DO(acc += VectorMatrixProduct (out[i], in[i], m), nXperiment, timeGeneral) - -#ifdef VERBOSE - printVector (out[0], "Output vector #0 (general)"); -#endif - -#if 0 // Possible test with a source level unrolled version - uint64_t timeUnrolled; - vector_t uout0, uout1; - acc += VectorMatrixProductUnrolled (uout0, in0, m); - DO(acc += VectorMatrixProductUnrolled (uout1, in1, m), nXperiment, timeUnrolled); - vectorCompare(out1, uout1, "Unrolled out0", doPrint); -#endif - - vmProduct = (pifvv) h2_malloc(1024); - vmProduct = genVectorMatrixProduct (vmProduct, m); - acc += vmProduct (cout[0], in[0]); - DO(acc += vmProduct (cout[i], in[i]), nXperiment, timeCompilette); - -#ifdef VERBOSE - printVector (cout[0], "Output vector #0 (compilette)"); -#endif - - resultValid = vectorCompare(out, cout, "Compilette", doPrint, nXperiment); - - printf ("%s;%d;%lu;%lu;%lld;%d;%s\n", - matrixName, nXperiment, - timeGeneral, timeCompilette, - h2_codeGenTime, h2_insnGenerated, - resultValid?"true":"false"); - return resultValid; -} diff --git a/Demos/VectorMatrix/VectorMatrix.riscv b/Demos/VectorMatrix/VectorMatrix.riscv deleted file mode 100755 index 8eea702214e5f50c8ce2d86440163b9568f12d15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62544 zcmdSC3tSXOwm;rO%`l4i*o=v6es03jFpkI$cQL_T?_FbXWE5Y!u8MCrqM{}~gD55_ z(lazZ5aKBKNR%J~K>|8NNlbj<$RH{rF=$xh3nRuvQ4^Dxjr#wd?im>n6gOt?{p)9{ zyQ`|Z>zq3EJ*Up8Y8Lk$7^+YxIOjh%?puzoR<}}cFHmM3$Ek35f%E1(I34H1{ho7| zt|^b|D7fCZfqqKl(~sd7h3hChmwrCDrXQ6do62X8ufU1p-`^caXF1i8|IwL(^E|*w zKWYcpL4Jnv7@l`lA^rNHS|WbbE-H7U1Ijy~oPO7FO+PAkws9@$uSMJF=Z$>&Im`a~ zWz?jpyEty@E`{`yX{j&&8_H4rfq(RTyq+71a@Y3#j6C`|=?i>q+Qh)uCjH^HX*1_7 z_`}?3uSZ085BkHj*JgJQnxubymi~{9y7VkGlQRw;j#TakdItR?9=FG@HGcG75B%t# zCw^3?6z`apDf_V7t55e@l=|lXy#MF6UW+`$yWf~PUOi*!tRMWB?{7YH z>6UiZMX$n?|NfL7>-vx0`wta8nd6?qZxVj#F4t7D&E@(zTzk7*kHhs}U9NwN>)9^X zf53H|%k?^3bC>1!b>ME?qjy%glxuN)&gGiq|G!+WN8q}*%k>akr?^~);(DLUH5WNK zYW6FUlV6{k7OjGBV_lKf1V^4h%D zr%sp_@k+$h$s9d`1Syy^4(uP&XF`y^`wR7_-EmXoYqKW4^4f&iv+$6~bA8cpNQdix zg>=Onc_bTdTnuWFOwzv(-b#hoF;2iaoEM$TUBh*za}sL&^QLo2AUV#L&PizSPe&_0m%<|bb4eN8q5|88Gc}~a(;UY0oI$Z;m`jz>StR1Jp z9rAVg`wg$#HM$<0*RXu$)`r*Rxec$|HM$=BUc>U0ISsGNvm0KwYjiz0t6}-dEzavX zbKFn*e5U<0?D*hgLywL)Jo?ah`^1A&4ou&F?aWbQgx4)?>C5`1T|<}j{k(_JWhv)x zvb0vPUgb$)FNX~pu*6WPUdNRhseD|ILUA3Jc;GE%O{(GETOKdB-ru?=W%|ASeSOSV zU)wB$V>OT2J_Lh>*&%9gn z?7F)uJf)_i;a)4Ry7Uea{s|FJsXDW4g-OVM*>tn-oXHxMd1K69hW72?bL)u;}Qmj4ony`bWCd4h_KXA6GvqkF7?j(`^}*{ zheQvl>}Tm@;CxP8OX$9`NHMdbr^&x6G30c}iqP)rEvzDRf2;lO-4oMTVNy5?N$bug zv+k|@*i1`dQkvV$wS`G$HZ!d->1ns_s^MMSVW!^4&u7m+aX! z-PO@<`Dul!V7BWWKJUYO-Q5%1^lSLsoV(UEKL5wNHP4*+F@BuSu%O}8`fs%z_PtJ2 ztgpS>eOcAZOOp$ChAK2Fu6NZ~bvcHwWG8f4Unn zHjbOve~ICmIm~QUx@|yTw5@q|_1(r#zR-7Q-@@h5FVC4$_+hl7Pz-NJ*+w`Y{0Go{sY$!^ceL0xG=NFs6ns9$B9J>)8Eyq%1?i&eYV#& zxA0ZrzuQeu71z!v$~9A;s@8q=M>-x{f9TJ#!*Boj&$?W(6L0~&{aJk9zjB&6ihD~! z6-JN5{(p2!NjuMRmL=!Ei;v^D9$zZB9<>V2qE>MlwVI1)^#jg1ZiyXF<>JNoII2OV zQY`?bfe_nL!>9*$nFWug&_)V@jWAad&M%8y- z(6U|$K1Z}=VWoph+{P~zq+ zakLKkZG(}ocrd>!@|WGGr@sEt|FO&qYa;(E~f9M6vyl1&PPoH0^!P|(Veg9{o z;b!kjLr8yXf1j|feO0gQ{s5!GZOaR>9e-0~G4D@Ed08{>8Sd$$R#DN{;?B95MU_hP zLnkhx^=I6?f0>PiY1!Pkl_~q<<7P~L`8SZMX!nx$U$FM(;}r?9!>Mo0#)Cx~aeqSR z0fi^Cdz+Up{kmfx`96#NhkLh@J0FOT`xZz8w2_f!{jIz4aTp=ycOl2~-8Jq;j?dX| zqIzZ;FFy`-e@@k-)pZ5ciB0Mr?XD;i+jDzVcar+AEK+m52d%V-J(xvhM9cV`?WPXW zom89d-lM|Z3GKPqq#H?xk}PT?XZi9)1)p=n+O4Yi^K}ko|)P`|M)QVOu zYK1v+(8{Cg#w~bM+v%>RTK=f}K(kv@ckWS{BYPya=bV%m-cl)ucd<#wo22|v@4-93 zEzOi*M%*HAu+@< z|7k8FN!?KqnrqhJ9cHu2-SPwS+FWwKC84FA3rZT7lvsRzhszyH)K5KdhsPy1=N;A+ zbVuJE&bA$^aBW-NF_~*Kq;hj~-SuPT#B=j*sTN%yrR#OO%~MzwFfi?BPSYutvn06x z*dw_;H!oSpS8^=hz_HCHPROxwL~G)}!XIiCpC?;tdnh#OP>kX8rq0EDPNstQKB3@! zYzp3Y631&hDtI08{FRDUNB*`$6)E5iG$t%~!|h~7Pu^_6Q%!iPjVtZ9V&G7Z-$oYJ z8Wn@omX)F0=gEA|ar4`bC*!F;c&aa+s#Qu)?pNx0cA$v^u>JT1vI`&lPR@`~FX$!h8w2mXE3fZrcRtZw7u zkYrtdg{!pAmHW=5-)SIutwQ2$@x}2+;>&sEA63;QRiz|}>yG)0 zONnBxM_h*0Nx=-$_XjS~o5E@5({6$V>T)R&oDac1(ZMLD$ zlnRoB)dLq+XovJVb;-D}GI&U@>hFyUPlOKfNbu~SH7~5{b-L%i=;FDyXG=m$L&}1W zj0sS{lnU+C(-qt@UA;* zI(po!d1}VDsz_yx|2P zLJv2KdnjbYaK8^Qj!l2tp%|z#?kHM<^mlvZKGo2((WkePr>MtCeMh1ZuQTlUi~cDZ--atALnTQ*|T_Ls42wfi?GiJpB#OB{IQ8gryQPs zXr^7CJLYE}yv!fg%ofd|g zdZ5D}LKQ#*;e&P&YdpEw5fO={-Vsl?rn430&uW175$j4g4XodYzQGDrXoT7BLw&9i zdX)y3)SWx~gG;}kyZ5~{wAdJ7@zgmnVvyqMYlB777DpDWDnD_>Thsj5Dux%)h1zn$Bn z1jS&Q4X6@S?JSrDM7ZU9-@0u!6t1=@3hOp;y!Smt>KN4!dLHjqitEb?)~z4M{1Z9B zx0Dn3RtmwVpF#*sRGitDHRfjNl<{YZcaFJP7Cruqtz=BE^57%UWx$P+5c8Rmn@1K_ zjIJDdLRoA&D)+A zKiVOWwA<1#bis@rPRcajgA%p7RuOvFtZ66fW6dqn$0fg+ciY^zaLqx^y0WltuSCml zcT1dktL$1t`_aFRSnv5v?1-ATO3%^Lm>zPv;5jZrXyr3EVM#xkFXmPfUzX%}+`6p_ z?f%R&itaPZ@vLKt8n@P`KQD|(@pO-P7M8_QFR4{<6zmc zNH9p2180WZ_wT2X^xemri@luFnf zT!t;HxNP6xGeb}BTsoq9^r`Vx6Hm-6PbisQvARDy+7}pQ23{S6R0EOz05r;N&9U76 z_bqKt$-e&HE8=O%QdxSZqhz17x#LNkI%o#|6u5HfUVg*|&u1Oj1O0e)(gkt6c*SXH zpS!m;qIH{AvShGE_KU;TKDYP12*JZ?jc3Ce&xSQ#Le@B;5$yGIo3dMiMmu4_Xbq_b z_x?9WO&nc0I%JG>jL+CrW8KEx9P|p%NN#1!Uip}`SJJ}==YLD~!Oy@#PtS~{9r;?=HHY_iBb0xUzXnxjdtOju)YiC%o5`UBLWhyMPU7 z#x6*{Zx@)#JCm-cw+lkaE?6Pk1?I%y(q8DlA>X_9%&c2hpe?jY1G`}8eY;@R%?MTN zXJjdm?Skt2c0s}Q2#eA&d#2Gm7&e2`E~vZKl96~9BXOqTjA3y9J^l4z8^hWS_-V}a zvDIV4#_byS2aH6E3e>39Jyo+|*Y${HtzWR1Z{I7t^`atTh05EhP2CO>&29(W4!a$7 zJH{*bx0+}lf2dh&L7A^_Y%Q!Gpc+C}g5VEL-n9uUp(1y{+`~6dovEBYc-MgF@|)FX zPAnW;HXsxlsh4agRNXxN)4rr2lxvJ!$GuoA=^uLrDzHm$2Ce=J!EPqp@qSfSJsI+zpd&Lvm6%1*)Y zdMjb*16IPZ@_H+wUS?(;m1SwagcMGhY=6}Cxq(NZ|BZ4z^T*V?pe3=SQf`GT#dU{V z?`VIBr1*A`<@4Y6USf<8TXS?~R@c1K`mPY@&I!5%u3xBU*sw6K!Gb?Dt3NbrS7=t) z+=4IcaMG?mNeafpr{Mo1G%xx~kN(mpawWFhlKj%0WxI}4Ra91%pD3%!I<>Jn_4M6+ z>x&tWzSOl+ur7&;jvc7ieas6hqATZ~c(y9^RIlouuoa(Q+V$g_wCS~lOaH=T8-Z*C z$wrXugW(SQ;6=qzryT?PQ>HTcV~0gFm^cE9s9o!Qe|FX?k3JIWsMr1@SUZC&`%x{r zm1wJuukmw-xo4nlEMuU5m?H~8?7F+Ilvj%fyJl&`;q?Q++xFJ8fm2U zI?&4=e5mK)yA?lGet+U-)%sH<)qD087w@s{EZJ2WUlvdDf8fs_Ic4WqzH5)wy)Vg* zWOX@Y$HnSuzcps(6S0-t9@kddy%Sc_M`SNe-u`$fF3s-peti^|XLoh3Gyik#*O3j{ zJc_qZZ63vktgc7#GvdSsD4x9Pe-FhGqy809JoG+_M@#b$X|~r4itkMYier2^QCyns z1vpR~xby!r6t8&6)dHxPaO)u`Ua|OQ6DVHs{EdbvF3DuY-s>(Syy9$K{ao)s6qoPV zbk+5az2A@&|KCLMg1mnR#bqjAI(r|*jn>e{C>{#5cku5t5V{}y2dLE$#p~-Vu5MW8 zKY`)}m+qr@#bQ?rpkkA30W^)`6?@D7Z=m?^=9HE8EEyTf-gD?Y&8$i&FE6RI?KGKy%(3?mQjCcs4?g1&Yw8xNU}czfk;gzGZ=Zji`+uy_bo?@sng!bRrUmKPh=04!&n2BR6$A*lvj`M@{U6Y2{ZksmV z5zE?mNt7)8zH>b#XSchK-Fw?A9e$lZIOfeeie#z~g(40m2ehqu{-sUInwDXaVmpjU_I7DcPJ{Mj6F1SOX;)vJE^6HSV+KyMZ{p5NTb#U<@*TNnHxJ*f zSqa~xz8z=z0Y0@QYM&*>Xi@U1AyT2CNQIc)ah}5~-b*OFb`7)cGm5UeBTR_dJpGfh zMu7i1wavLZ;We5c&(YJEAJ&j9fN!sDtIoNiq96HdF&A$o&BYa^?c}+*8WCFFJD;mD zd!D{gShK#(Wjx`jA5XhJq2@QOe%4HW8gI+kXOq5fSI>pTYhAgpDa|QU z)H}onIX)=K&+5sAl4qkh`y{x#>CTC#chvm0=XqF=@MDeG(D`7oQTAf3QH&*z7Cc$x z$C|7-k2n#(;yd`*m0W4>6^07K>VBvCy*&^S4Mo3wp0>X_darMx)RySrBhNze&q`kZ z3!y{%#Ez_4;#vNgEI-k~<iq}2&a(-xno{zrbvSZpyP}WEcnD=I?FUDIg+N0Fg< z$%Q|3!c!UEC+G*_U3edV1d=~cA>e(L9)-2xQXG@wnT}Yd^v;VI2k_$g+Th89zd}dv z?5OB?o-_0WqZs*VZFShG!BwLx#+Oe#GNo*K>C6)MGb6~irx413UM^8`iZwc8 zjE+dT994|_`B_J#oc-KclBI;7q_~l4WnIOwZ(aFbcN39F$q(QfDX((+?<(r*B38?h z^3eN{a>>VqXt~3GS5bgb{ODNuO~eW&4yzm%GRiv2XY{JkZewl^m^iR_yD3JW`FmUyE4z|3kbkt#zx2r(;_a=P52^>GU&ao^m_6vaKfVO{s6tAGJja zp~<*1`Hc{zt?h9?ro6g|m@@LD2;KI*6rqchBXp&agidSz^-YAAha0$nh(xT0#Qpmlh4HNrm^;~%MorK_c85#7ynNkW1)}CJ7u7$r;hoLDfu7kqa$XUw8M1xM%je-2Zy(EN z){f<~PL6%g$m_lv`@WIaem9=?zc`lHE5`zP$Mc+RJYrnq5#t)q>n@Iu9m)GDr^05O z4jnlW$4R)J#CzB#@&Oko^7<1KVUtWo-V{7x3eKnU?zSnoa|-W&VhYx0MdF^RD0>a( zGx4MIsl3uQmDgUJ%Ii){#XZyU=IJP#&b!&B^S&3S^V$=1{TfyS&BS|WqI@=vb8#KT zx3j&*dtaOh{XG-!orN+w&PLg6-qSXd*Q3n)1l6C7ch5!HT(oyKj?uVYV2(t~XQSnG z$6UNU3b|2yE8AS~VJ;tVg6@byE2B^r4Qir5O;ko2=%Jj2C|StosN--~G};)A>uAsu z4SJ$MPc+&yAN3aCxB%q~K+^)yv;Z_MKwZjv6J?9gzJ)k01jiSG;|sy@g(zEyR=tU` zH$mq@(D^3lr2227Rf|xz2t69lXR1x;N#q){wI6k*F4(AETOXTxT zQoVRSAHQ_mmtc?Qb86%H+>=z_1j#U=%*31QCO)gy#OItefsb#3k8gsH)XqiV-y(2r z5xBMpQe{ScJXgI8&r85{0?rd4T?vq`1V~o`%Aqw-Cl|jsdm^7vo5*LLOhh}EqAumH zK>12sr{K2?=gat&sFz;5jL$f^4CTwv<`pPg!LP6{Qy+d z#&IRT%)Wxpt6jn8qfQpC)A8I4{1WXe!HbpP0o6}IyHZfL3Oq;w59mA!+H}xJ z*O|!ALj4T1Ed%Enpfdw>W`NENlxLtlnJCKyeVL#y6ZB=G9a~VB@^et0i|Z^Lvp{Pm zXw3qxSt!dwdvZ{g1NyQ+AKr74>gS+6xhSLi@^H+@^)}F&16p%HYYy786=k_N=AkSP zH0FZFT+m4O<)K}9D9ZfKqHWu8&o&&bxVD03D`>WYW-IDg(WVbj_5tX$g3b>>C*4PRAEIm* z+O`wNouKyv(E9=CrDyI$dp<v#n)t0mo%Gsb&{~Z0VzkGGG8661oYuOCrePT6m2R+SsCb~ zV>zzNL1!uGEJa%m;hr)a%aC6NTFXFV8E7m+-6Lqz5tLztiyiN*rSl5pRf5(dsDA`) zE5~&?Xe|e=<)F13Z8?T|bgV#m1!yb>jTNAg?xnmFD62x-@ErVB*egJ51!%2ATRufO z9Z#VA1Zb=Tjg_F0>YhNG=)O}Zug3Xl9IHU@3DA22^qxSQK0|pGj#Vf>1)8fsYZYj% zLfunn*C~|I?=;TOfZkJ}_Y~+oh5FTKUp4ZpL2otatp=Uds9TLTokrPd(1~}}()l^$ zT>!nO(XKCW4;{}S?+oZY4SLUj-ZQ9o2JJbAvU8yG4Cp)qI_X}@yNI$&XcwM?-!l6- z(0UHEQrQKx=OW53g1!r&?*izfdKb~2izuV}F5`Fw*H=L2MbLQ>bY4VTzC_t29512l z5@@^x8ZUvyOQ?StZMuxI%b<~t-{AThXuS+tFQfitwCxJ=u7K7np!Eu9yn=dH(57!t z_6_K}0{XrIeRO>t`8QGj8?@~j&aZ*aZ$Rfapz|8qQHMHoypHngpz#`LyapPn?sc^1 zCdzJt#_OQ*I%uSNH_?upDEkg{-2`2D{>htY!?%3SyVwJlzm$(ZpMZU6rLSWznzW;C z{r7iUM_AM>&(kYEO%++Vyteo4`5Ih1ZMiwqElK+mG#+KZg3u1T5V z&S$py&SJiGgU{K`@#*-PHhjnDw&nOd{POY3z%LWOEJR`d5QaM0BdtauU>RcLWhl)a zWi>Ki4+YbODfrAZTnYZm6q( z{5#$|Vt7y=jS}(EQM`|4xV2wUA3k#`j(k?)Fr+!U;g(k19p0bH_`FubusSL=K0IhJ zpV8)fKE2J4eEf#*`M3=~3OQ|lycs%FdNSKQ;CtTt?#Q6QPlfx8Whi^Zb)(-kNS{v7(wX?+daO+?`x6RLdPMf>@ zvJF4;i5u>MxA*S1Hh;h!KK<@UtIXSs{884ye?y;b#F5WhNomeCl=8Xl=sa&crRnWP zAk8SJe)FA4sdgpt`>}c3+qJd(HvJ6V_TjVIU|h6u;}bT}n88}(kf%+#qyW8cD7Z>Kdf%t*7N;Z#@A25!!H`Omhzh7>j7W`dVo@`Fbt`Vr}KI& z*thsJSwN{G%JzPoXaTV zb6e4Q-bhN*Ta7@Paf+UtITb11nUy#K6zVj%g0$yKHS(l1T|%pjQo^T3d__*~R6;RH z2KFA8kRYo~J4kB>NNYPtYX?Yc2WLCk=ELot3=&L!Y$VvMOr zWf>q%DQiesGeWzgOxA{^32~mT9)UC?66p+#m&kBjWr>uRLwTr6X`Ym(M-In%Mkl22 zLI$L(EO8js?LsBFRD!y|fyLXc(6&MSShhL>IsXvy-N&;0(6MZD!dPK*NraH$K1nDD zox}%cAhL1s- zHJ{FN!YR%DfpYR{DNR2~G-cQ&x+96!EV3Q=oFb&fefeBFjuT-8oW!v*lusvmHDx zWwQpmPX5wb!jIB06Mb`sWvP5w1$LK|B^Q*sK~MUW{UaD6Id%16jK z%nSY^yjl{!{ku#P^x_nzw@+cbI+FPrBLzP(l4u3M;O$cdAN4dLP@KjB?bG-S zsedx1{>hU1C#MVb%oFG(w66se4XMD}^4j=fFZbiqzmw$5_fpQD_QK#a_fpF;kC9Z)d#hiwv`KNVO6gf5@amZYHuj)5XQDS} z3VQV{^!zyV{CGiU9M1y88G^5U2J;ig3x4+TOsk$CXpIwiZvKqwl$iPMW$@^Zrl;;o z=`Q|55!A2eksu?}wR%m}pZ6BW1R1e+I#1Jv!#>zFjO{y7S!ulQd^#J=Yr|=@>wZ8j z-oKX8fRmJZ+eabwi5!X4w-cRfv*}z{g!DpR-rtVn&`{LIu{f0X?gA^G_fdyyRN@RT zuR>ETW*)x*cct;1B_Ui+xHPsUu1nl~{+t!Kq15y7QGvo{<1ChK&;Dc-^&Kz$$0`bruBbA?RxT;~W7 zT}Hsth9f|d`(3GCUcqTSOM?1Xdkfv{b0OhTknkuWP(2+IJ)P;q>CDeQ9cb_>(;8nD zwBoC*tN1$WrhZ-UH@+Sl&H~vSLEmQ%(+hL>{Bv^|e*kTsJ;vIb&-e$WnSZ4;%bU`i zb0ow5B+-0;B+uSINYX3Gt*`pN^n&s{S%Rh6>S$StrP=C8lH}Xbm`{!fUenPlHmtt8nC)}<^jhL!#z~2jc1p7%B~31&NUp@; zyjoz%OVG~DZj55@*Oikb{CEwq>0YCH?T=(#_-m2xl zm2if3d!}&>kS5xK_F31&O8oBNrB5ZE2bBmu3E*-`6bp2pC+I`xF@4EAtdEKgPK!a* zK^?^Vt6#7n-b3?qiwWHDJQ>7$oP5E$nrIWdgSHp7sWJ0|N(oamz%b&$uC&|HUWgab zY#Y11Qmw|0Ue?s$ve@B#diZEQFFVR=R2eMT`^RU{=xdE}FO9z}Y2@W(OBRDP{_-N} zJY6Kq0P|_+7HK5XH80^dbUdBs)*=Odgfw7P+u#71e*e?Dm)y}Bz; zaxrhndTCdxQ%})2m9-S~kY0>odSf(nb+n+fM>8F`#~T+wM=yYmUH}~(150GS;0JDM z?ekfHdV!>WBv~Q-n?;iE%;IccTg#g>1U`NJ44!~8j zLDEf4==yNtc`iv3@l2AXbXRRJ@jFZ6cTP4q%IA{i2fyR8CYT;Sj9z=+qGpZL1qXMY{GNEB?5D8bkGChKN@ zL-1F>N$7nbM$of`Oy6fApLy<0#tRFZLhqE(Rs)}N@jr;(_Jxq@Hwe9rZvZvkXgPWh z`HVOTE@X;tI?=n!%dY6HRk)(J*Z{r7hm1->+1t^xNk43MT1qE z9lUt%VlTek#a_=nfX=}sLPlt;P>>MI3QA%z=Uc?`6Be<}C5xKJZ9%8(#dNlp_>AmD zgyF#N{`L6X_L2DA1*q+c-*o*j{O%&@NJ$quEW#p;yL$XK#=7A5zLzclzkQT(LZBfI zBWf`VG{s>=E`B(E8)I3%7|S->V}bpPf#HjVTqCF>jKNHT(o6}(o1Mo#E`Hk=2|4OT zEJws!2*1^f=}iyfcQ{e+g5Sy8n9&sH9FMN^iBS#4S;?g5D4>@X95Ek70=rXj;MomGR6EJ>rKR(V{m3 z41HwIs`@`E^wy|sSb@+O!DY#j(OWui2E79>3%n^FeAX!qe5yB#&pWQ-~%YM#S4K-fdv`_L2nb7UTGo(r=EP=`2?Z2MrDeZN5X|> z?C%!a-uw1$XGW!o`I-c$thiuzr-xbIH2aL5@36y5L;666n}OeEp_|dfx``&i-)>@E z)n@2-v$c1Skp&9zg8o1}q~{Gt&l}87{ifgtOxKEU3R?S{OwR$-t&IR{4ug*xr*!#+2ffXF(#fHqUx&}+34%AAxmy)+7&w#4^s`mvboC$kgB z(;8UesST{~mgBh7wvy*Q0xw1gKK2OAc_zWKngq^Az=E2@0@M*Ph}$`5>|S2(X}1^l zB+tMIvehh{f{jRXPm77^S*B^-dL-qA;hN_3uul4E$c|D@>d*8B6XQ)LL1!~Tmd%iH zGi2P%v^KL4VCsjNKjuBsjAj_`Gau()`6Dya$U~VW zc_?$jDJNG=Ipn9@R(FXNUte=W^g<=X%Md)CNiBNLC~5+*2NIU{7eagpDlrD4I-c3Ny2%xg!44xz*h^gs;G!Y zvcnHx$N9w2V%Uc#aaM`heHvMf8MTyVO6OUUCUeX|D2H`HdmOV6+3KQs26;AQyGz0( zX%^zD!PfC%ozwURg}>PR7$A(df&S7yf~Qm zxcJxSQg6>Abf6iievNYu>gh$Yo4ZD~XY?iVOjPhOEp^UDV~5jxl=sbCCg@BXl4Zoz)^U}Rf=@|G49f+*X(`&c6m47vt-AtRcLlWW3KnQv!Md83v2Ld2 zg1>F~!|b15CMAaDvXo#fH$7MFqFgTM4A|pgTh?+Zc|L;~Z7UuvCAXt!_L!A&d!f=R zVYO`a5FS!4&0VWfELeCz@>50r&Ijh3+L9{AjFSZ@G2_{pf?4M$A@VpBw{(!o0h{m08PpjplKM!W)j9`k`QQE$^5{5KX6}bTY=t5lI&k-hg$C z5*BFEjI-@G~|wOOz0t~BwDCl9dmq&Yfr3Hv$0isxdC>Fur^p?=gw2F1Jt$H}3h$IF7*33zx zGOVhX4m;3sXk+hJ7v(C*>s#RLTg@YiBrh&{r|vWm#p09_mzh)Aum)1%M3k5}>Ji21 z^CCo%eO`npP0y3GC9)5T1t?eFpDB%RFjJZUM9~df15U5OSXu=Q4|;5?m=4_L4XdG@ zRzqS|vp~ZdAc_TuVgaI9gaE??C!##LnUivLbBL1WqK6{s+!2Mj@AulbX*Cc9{%u~T z{0C-Eui%@9X^@-M=$+L-lhuMBsL&eL08Q2aX|MuJ`3m^528fahL`emrqzZav8n}?w zJfeiR1X0%1%Z%7UM3HG~gecpdKLbQbW4^Xjr>wZloEmw(VkIBCJXeCRYb|_T>o8YZ z313$-d|k=#btS{smCUs26!^L*V&`jID|8dn;PFa>$7`(y7ER22Yww;GFRy3QdX~o0 zij&N9Ym0ls69x%ksqloQ!V89#+_T3NOECvp0eJodAoP_W7 zPI){mH>_)fwF4Lrzbd)Pi58(L{c*4?|uW6H0T3qnFkteJno{R6o3-d14RuI-<*S&fz z^8w1>J6ZS6rGwJY*rNc9p-Xxyqo=Yb@7dFCA1_@!{X`f9^;kh@V zI%3ix|3N%ArW2mqH^CRS3BEA&TMO}g+gUr|x&2-Cp7C8Lp8s-xSR*{Ay?EGXcOTDN zVXvM0#o3RC=gN#mc&^LLfK1QA2%QZy%m5l@KyEXb-msbRrp*u9=1s*lFdM_(rN^7? z*J5PW$EF{gxivH2-&Syf@Z7dp&?~8x8E9n&#%d-;UM5D~7L2?tg1>UJ&`p`ix*0Nm zJv_Hd9N@rY#Smxhyr0 zw9dEftrmDgHqe}Qm2y$@d7okLL2kC7ceX$eWeI+uLTk$sw4gM*KgBhoS%4`^@G)fz zfwpYus~kaZ$^jR0ei@n@vg>80X*7RuBt%Lxj>c#nn2A|j4)ZnSIAz5J&6~8&V_w&+ z#5$DJXE%CzX_$fqr_HrIi*E-7^%1(M-z)A7e9skhKyaOy&iw4@f}i?brZv8cl|}Ee zz&?-z0djC4Tky5NC-CZA!N-`(c$UMu8Q&B9#rIej`@2nHxon$9k%gW+jMBXC#vo1a zI0|WolG4n~ks(rCqxgPYBg7@HQQV@qhP=8+w#`A05wzrhmK?MTz1C7JZ~rx6xtQz3 z@n3G2%kyZOCuhO)Msw-Mja+C;D0aaDY+?{uBnu>eoadw%NHx6SCV0bbiGtn$|ECgi zZFo=6ncibM+k24PrI7Dj$agO6tXyDXq7Yz;;s5W(HBuIT{$O0gmW#1V`?YCrw#Ou_ zIA|2tXf-Jo5!bCur`!sQERS_DAo^z53M*|Z(<-q)^})D?4Le_pS{T=$IgISDrg@6f zUric}by3DP^jX(FIuTG|y4mss zf93nXUSz|Boo8et7dIQ(Fyuj+h_m2gb2?12I_o`5+m7vorJ3)H0p!XH14XrJC2nc!KEF%ED2%&m0MG34F?~0317Q0>T^x^*Lfr> z^Q@b&wgV-LQZb`<>}b;_SWL>iovS-~A!3*>=*4`dx92lnT>$&80CrwM7FK}-ACbnQ zyE|}^VvdNMs8o49%k^tQjGkV(YxE^ppXZ;QAB44e9ldyOTHPzH@$ivW`1;yuov${M zR^RBdr8PL6C?`OT6j35?5wS<2(5sI%)B^hWj7x|XR)+GvB96S4Rs!=nHKqPi8X%?K z;s{zRxVDd#B5Mwb63Krpt=YSY-crM}pfMZskypP~DgA6QaBs7H8`fKGX9ePRwpG1N z$Teem`kCZ%^lJ6-~@@YTj+7D_i*+<}q zv~~~FBWea)JKJ6W$u3|yVgWod+vr`*NtmP+T_mg^1^3&ys%WKh_|G;cl1g~<+*UhgOU~#Me^CRJY#i; zk@M27_9?kDjMt`FNz!=l`6NX?kw|+jx8V8mT64sjB}q#|S{Vv{`u`wF8%ZVaEk&Ds zq&4Thk&<+EqWH5;TD$9?O*sK1Z|D!m7rbC9`}T%X#%IbhCXHw3ib;|>S`oT!NQp+h zyn9EC5*m*o#%j?5D*~L^4$cr)tl)|j9=<|BYb<2l?8MDNcmcsp^#_99_yN<~Kfnmw zficnjxwPUw#2JQf-Se5253GGG$mP?el@A%x%7@IlF+oFk?b$KdnV7SY*16@{#vsj` zMCY&{kivdI3i~0bFOJg62v`z1lSg5NgvwmV=h6xZP#jP-QsP*;X@t@%D~;s^s(H13GlH2F)+$15|4j|eN@N)tRFlvi1YCnYK{}D#+ zhZwmZTGz7x`-g;Q^t2K8@l2DzVQ)CuoV2=<=OXLT3?-yD2|ckoKB{NA&pJZ0FrXQB zi|f05B%_%qp&4P?9-x`=e;T4$7vw(?H2bh=Gz*vJPY!-N(JX!OZH?HbS3R1YaiZCW z;0y8OBk<%SpxG{<*)AYG@p2c?47^l-3^e-~qwiykzE7~asF#dpk%VRnK9B#H&`jN{ zc{I}#rsbB8!4B(ynWGWu@YXb1<%QK=_t9*gjAr=eNFy}!P8^}Z2il99#50-h#&}k+ zPr|cLU=e)mlr@(~ai>O+;s$XYakt=O-;H@^kJeEI-<`T%_TfNAX?2wL?H#C81b zpDN)08F=Uv8{P zjC~%@HdgO}Ebn1@aS!9|djy?vFVl&8TWlNaviJNFO+pkpY~wz%Cb2$X8)NpB>#&+1 z(>hk~X{bx;U^NPx#eG7CeIF|@?iaS&_p+_(eb5X0gaY;cN9z*x9+nSoZ5HWyO)%UO*BmQ2FU3yn@x}=eHoPO*KjdA0C=lFh1>p0Y@OB!0o>SDpiSPTR# z1_B-s^x&NyyyL+;owyGpW*<;;Kl4-X7yOL-gVwPCald38<9QES$Fe?2XsA!_&%>Iu zj(yXLo6;wCNQ|^^?Fn1Q;{K-fNt4!b`r_3Zae2Q7^@+G2oFT3hgDb_r$ztH-0il~n z+&lm*J-`C(;HKJ!F=)dWw81*==b}%rUdm#VtYdul;K^9WvOej1-~oN|xYlvX*?*Fx z*=?9B+MLqXQf*?yPCKzg2sC~I`S}D~`UG6s4KD4*is{{g*1nsfO5#E0Yd;7(3 zJlLc*Nk3OY+N2M-C>(%?@&MzRt)VuN;z?Qm8`?yTFHHkcZ9rBV>taW{TB=QEWso)z zOW1qr5~nr^Z?IctM1$Qj&F^(|%u5E=YZLpRrnHHAAm7N-VjuK)+Qg0>aB4f#8|{o2 z?Sf8S%5=uk7HboIcF8Z%CTdXVn3oJ{PMaWp^>1nudr1RrlJa~WX%piiAwxXG3e;u7 zRO(?-9e=gwQN9*?3Cjn!HXH3irX4ZFUvp++EERG@JLbKmSh-S4?`oko zNx65M#<;r7IldoHn;8GrSewxNMBwdZf{*$z@b572@35c;@AURk*wcqFQVwCn90Ep` zF+cku!B1UAa}#5kG&jNX>gOg-U(3ItP5jf!n$jl5zx_Je#8}p}Hj%A#hX%htJ4r6U z?BwqcY7=7_I73`116K|MCl3QB4-4Ilhr!Jwz|tcuP&@+Nd<0|gD8}GX%ufF9qD}C3 z}*~#CZtTs{MD}aq=ClApkP0meH>b@sQ6OY2SI_i|RM`@FXMYZflDXL{W1{}iQ z!89IZe&RvF&wh|;)g_qKm0*WFc-05I5{@umu^dua4n7`Z{DC8^o4Q=^HPyB~b8t~m1q~0AzA@xyG>ieXlTA&9}E%i~*aun@4+G1UjvUfM>65}za z9(h<)t9d=rwC_P2;hg`I_8-aNU8}vkd`h%wJUsW8zYiTDBucJLY6Um=S z9@BtYO1)1?`*x(=JHFEH9j&x`MC3u*v^!L^%f`Rrd zf?jQ`QPU*OsYl8hH3WY#7~d^9M*MSn{8$&Xt5N(yLb}F#eNu)LkuFtN3K_;qR$#A$ zhwnH%e8<^)_TxfMrb;QQT)mv=F3BhTxQ5HnUI(TKIb~lwE z4u*YAjqEk!gy#Inh)$H!wgPifB_ zVqo5xClF!&l<7^MGT!#7pfljFD4S03Qbf#5u`wwkCdI}ch>Br-(5JkAePj%K+$b&v z>Kt?b2}AJ}3!38>V=gDjRkM+?v?d~Bl1w%Dngw6)!B0tk3)0ighW0Dbe$c?1J{5S= zXIL@xnGmR~!iu3P)>V0ebyI#O_!~YG9`c2YUt*zQ9~r)A>sXQ4%nl*b2|;K3l!3d= z%Ty!JaZ24;tQe|tN|cM=xZyrB*>8-mse5^K$Crg1k+6v|_^yf5V{Bbd@+8gKCpxSw zNoHIUS~vkR8sT{QalM1oO&+J zifC3O{(_3{=k%AGL0uInIthwSVr9`uK?@FaGl5dmDHdo0HWJ5AbSareH!8l%rySHtH{>2k5g z(p){ojv40Edc3kvdl0YG_%>U^NWOjA6UM7*2VUtis|CHG8a%EBkE?-K|71GTKU<7f z)eqv88q_&vm(w1OR}z9bv|wWytKaon1ZyAt(^wbAZNfa01=#)x8A1C&18>6mHPdO} z)oI|>7r?781b^i}g>K5ztefHV!|_V|1^bU||9m7~{Zr7{su{T3JYGq%RUf-gsap-a z`obwu;q|f9hASMK#4F>Bm^Xk|D}XroN*qa3_1lP7&7g0@1*c8fa65Xmj9ANIi*2w- zF)Kp1YWNxFD`dpVT3?S?Rre7Kc=ZLz4t8<-4m%6ppJjU6Ke6WVG-T&AWaqTN+rGe> z$1_5p;S9#`8LW9cE%>27w1zL7h}CNaFblR5qFiVb=f?X=5qqr^r`Lr`s6|)>Jr{6N z!Yn)4nhm}Yr=}bo#p{7qUtoVY&S)IlafIA8i&~LVoXf#&=S(uC4qvwOoYm3mLIc!N z&jMoBmd`OiHfqTfH;Qn@ZCVA?Iw$xW&N*dFbdfQWOO$14WW%q6 zXrx$`V+T@+wKoe;o{tUZy)RxspPvH7r@*08;Lzvb(C1iD_qm`2J_Z`V8E{B%I}3R^ zC-~aVV>Q9eYtq-(GNrGtVb2m)Ed1(U?x8(PtPAy*;T)v+ z9L*W!m6Ehm$x1t!RLb)__A6PX{Ypr&UkPdbh>bh@Irf-b5PX#vS~7p65nUhE!ry?q z|8+-)RXev{OBkab)Dj~8GE74)VT^jRTEce0p(XU07a-F$OmC=Rys1XeDK9de;i9Z1 zRQ(@i)!HsJ)Dm4r!5#p04y!iGsU@tiYP-;=zHik!V_Jj*@@%O~xXY{&qnGqV7pYI0 z(-ZA4qGtn47X`iT0wXGTLk;BaOUT`qLZIzSSY4L{e_M^v&32J>Q-1mD=?T-tN9hT} zMU0*r2L85KPsA;@Vin;f=NNX;6AgDZHK`};^PAEW_W3Q-6EQJl*_Pec6SQY)#5%HV z!)R6%V7TPa6#m0%!Tnlb;zeL0XjFa)`T0`dO_!jpFF{+^vOrTU^FxpLp+~gJOR}a= z_1|+}Q&6jZxu!5&dQej|mMN!1$++1_Q^ZZUEL*fIVxE&$cxl8HG0=CHB`x8pyi6Jt zyLG>Urf>tATmqV0f)2bS_<>5TsTNpR3*OWMD=&lU%izpqjI6IPvc7U^iWM=xR8ycG z&1ec;cvEX3~6)EYv}Ju zwD=31vZgShzigKw$zL&@0sU4B45F`g)@uvfR}a?~b>G9j` zgs5}ODHgeEi-tZBXUwWzTRi@(B5(;=yZR_?p}dL_1pXSpUmN{} z7}A4}-U}Ny&4uaFLL&Nb6YH5a%LM5{1 zs7|>ZjW1Bck4C#`vBnoO4EpjLVI%1bX*GEQ?XuC9bQh;6Sb(z5p)0(H-2mUO0}(+T z_^Y#Bh4fs5#;$|Lu7k#|V}XY2%+GL5@Izl{ZP%Q$ih5l^?fB)oLRt5qu4pV#PG3mV zx?+=A))k&6r>^icLE~MQbcLJprlc$M!)`!VFhQrR1D4b=KTzohDz%2|K*HGJzT?n*S3VQJ-)7#N{HTWr33OeJrh^Krj zbTuAlUB%;qul+dlvwti2tG~l{p;ucH>}IU;H+y3JYfxIonwV&PDWXurEYP%8(v9iv zoZh)!b_9KkRMR%aUH%#=&t*H;%Z{Wk3X&BG|0rTqs(}_yjAid0(A=^3zMM2eki6e} zOjz@8c8yKRktu1FtQ4KP3Gd~j<5MB<8iZ36%Uc}oGP{stQuIB!Ea^LQIZ}M8{@Zf@ zcxegk%rQAU297h(!LpAkvP5AEqET6c6hc;#f-Ek?K$h}ZSGkZi^d=Sl>J|PnR>o1R z>i+^!sV(?R(`xeeiy>*&P%rE?^x#;xFw`J_zcmzp0gK~(MesoATE?-i9{8)^X`}jM z7E0xUZy0>4(hNzOCo%lJtV;Mm=7Xw(SE5tfgQ(SYq0~POkvTrVNavs* z7``+Fx|ZT!mxm!jh_5M%!%?P9qf{pj)2R31Zx>M+=48X_;)WD0m3Anpm&+CiBw&T} zOv(dC9Cco}1@U;>(XHoY{ah^$eaoGwv4=uwv z$s18*aZ-dkL&;w0cO3dyYQNNT)MLcMAF#_ugJ;5bfHUkGp)`HIq`f6n&6MUGSv@F6 z`YIRNoGW>t^Nf_2E)IVbMZFtP)czeuAFXosjNRfqQ&XPYN0irGAFXPxkA^>XAEAdI z>?4bVB1!5R_fQbYDaoHCae*l^HR2j44aPL*nUp6{Bjq(ijku;cYDPT~YK-`s$CAV~ zGlu4X9v68N9KEy7NripA^Gr>7L`6T0AiN0=2F&E*Lk;y@XNPtknJB#JSmLFFSfE-ARZ2UFVsa@+69+ zyk;m;r#B~clb;AZ_IDpHbuYV0-R!gfbo9_>Cl$sm&NGqnL z%fspUV?%n%9sQH-q{5!#JX2Gi+&`4p3_a@X=IEL6MCh^SJe;22H>793qknRpRETue zpzY9w7!inv=0YFR*zgUPMhMwT(C?J`%TYEXolEvWbDFd9_-JSeY1ACU3Y`b6p<3sc zc4yap#WEG<-$!cH^WDAnxmrJD5B)~T=PWTbuz6q$(O(rrEjtdjV{9h`NV&+;wXH>#gd_)tmNp>|l73Jq zG1wH^O(_c$x-Cs;U@1#6&?IzOpdoa`IoZG5Tt-p6;Ro{07@d@u&E|==>-gu~W+4t7(uGw_c3tKwz zztsPra{1J+A8qaI*xTX1bo-@qF1z(I`SPO|bvEs7@;7g9K0SE-+N(AE3UceA))yYU zZuz0s_`eeW=>YHtdWqjN-M`-FlJ2Tme}6zIK9{WAzY*QxQuYOQY#vc|-0-$M?}jS( z9%a|yj!j+iQ-eDPXAR^3L;-I-q!db>Q7>-}tS_yH3^{k)@TyYf)WExA(^TaFNUXxU z>`jo^WJ+ufC}(Vv*OzYkOo>^$*ZX!sVwX)~m%I3UQ1$V zcZVr4vU|y>#J=52MkPje?+J8VQRRGDUVPggwB>;t+%?iqoeiOxzbP2HXvXgArd6GN zK+GE~c1{yR?c?yv$KoTko#gjFlf+HV(gJ9IlSVN5;vIjFTT3C%<34 zWB30|+i~_`@xWm5#%bdEwYhbT@P%b$2tc;_p_yYT+h#WZtI3z$D!)XM_ae# zIIUp_o|%D|^*2DUot#G&e+969*)1)0veqt$!s{Egci&kQ(& z@oM$3R5a%~YHQi$dVb!9?{6v2bxKFV(6VvEU=g%jc;w(Ib4TS`Hg0dE+-rwJmmDaN ziVV5Owk+K8?YD}jHi!pqn0Na??NCi<{aeD>xUXiU7C9NYz(|8Z8_pSa9-RHrv7^=7 z8;kp92tV{)zjmNuC~)wbZykI6C$y&RnH5jLmJREcN{v_l^NrQB(59~rhSom8>7P2!SZG8Tz-pXF^{;f=&n>11C>=j+yDT5_z2SP_ga zOR|P?Z!j52_W)kgq{RSM8z8B5w%vA0)<){^jISX5pTDlZ8ee_@@-)_chb ztIhJZFZZ8_d$c|6O($Z_>TOFe!;V;S_8V6WzFuBbq)^!j{0Z}Wl$ z)V~beh6{z_eX+F34R3&>mV~|O9xa~K(veUw>P;myE!>yzmiQ{V^m=RKy$N_~It>F$ zQsW8fQJDO0M75oWIh0VZ$&0k=MdtJ%QBfEzyURrc@OYUov6nNyL&R30l-Z$ zv=gu+mC2mvLi<*u9>4_PJ%F#Q$z=Wrxa*IZOluDGe4NRI0k8ZM+7H9rU}JGMUp@o+IhBvyj~m+8ojlC|iyABxo#S@FI2~ zj(|1`Q1}Z9{hQ_bbyCx?e~-U_B+B(8z6c(4wI1doy%F&V(2}G;u70z;MS)=69{=!? zXO|QRzemtfA4YUH!w!r$_`FL8TrFh1)v?vNPEvj+DByqAzt{hge_x$0CfJ_$5RXD` zDWFI~|2nB|7;0&c8@jykAur1iNSg&3{cn;^F=+Ean+Mud8?DadTWq7P1g#Bxr8Zg= zv@X!tRtDCw7PQr%Ez~InZ2+_(&=%Qf_k;F0X!bfD2ki~ed^WxpK|2PTKA}Np9dCj* z3-iLx_eancf;QhKn~%Y08%Ohk76Z+0-vZEX0nKjT63`w7?L3=4&cFSjRoiF@(A=1N z7Oe?o8$eqC+T(y2&-wn_axSyRbHH`GdocG7&o}bdNke(^6M4gRd#s`LzwCd-|Ehn) z{|o;w;aTtwe10MBgPv`ej~`)vLEkpX)HdL{Er;5M@~H353G1Y-PWi>p)c7mA&Qj>| zW3Fz;+!S>MPfGP$l#b0ZUCyp@$vTO(C=TfaYH26ei*1JG zH5R$!&jr(S3!&-&^u~^$pOI%E?E}zCkK*%4rx-LhK06M8CSzS-I16zWXwUyXlUYFm z)>;2nXDe-4CvBGH%F#6zD=hROHi7>G@ayXW*JW!Guaj1p+;uNuQe6q&e(;J9GMS?Q zqQ1b3@n=(4=MDQ`s^6>6yf%un-SQP|<~~gK(ZT{RjWCvcvUFG+1!8#bOHj#i+K)OG z)Z+8eSXUmBE*mRkpSa2*8C6pYJ~PHFEWfHV%%Pzt!^s{v*#jqg;A9V+?17U#aIyzZ z_Q1&=IN1aLA9`RrE{IBVC6SNFBhnf~FQVf$Nt{lII0MlQe5Q%>%$N_H_h2k%d{mOe zho5HRZXC353=^vqN$@BX1ZNMCbjynO0&joAlX@vtQlRBLDf#jT}H`((cN(x<%Tnm!x+sM2A-PwS= zaQzllyB^E?3J_T+?ErcmHzT9hF+oTq$|U5JLsGc|If;q<9nwA}?cYdaB0oZ!i!_d$ z#6}_2){4PWMg3@}z=cK!^Kv za(bjGys~qLACksI{xNA?q;X&+Ch`lU zd10yY3(}a#2T8k=eD9OSME(P5*PyA2ghXN@dzjXin(7h zcRq9MR=I&Wc87d1b9Xa$IdeOi)0q1ib8+T=&Dpj`fE_-ZcwPm;Z%n3*(J^a3)i$>8$Di;@q zB0#watkN{k*}$Dj6XuX&tV<4kRhEjR!f8d)q=`zw%z~1FVl1(;PbdW!&S;!MGMwdH zs*)xO&*_fFVicb(2$aw1z%f^NJQsKr+&DU?LT<6=T+cZkGPow#&_(zJ%_#=qJS@y^ zv&2b8mgGuOW3dF8ywjny928Hnq!f5Oy0+8ZEXvn~PS3H_Pbh`9Szs+Fl3=$-nLTrM zAwGX6ng+Sihp-t8Ma7b?3Dr^2B-2d2b}VcQY-V0KL&n!qlSeBzMW#$MG@xbFFx3I$ zF7S9@z0q6}r4e$vR(!xA%F=9kqFjxfq$k2D^J7n`kQ6Cb7Lp?Csg&zR-k?~iV;sfeq*T5s3n}DK z`4>?GElRPb<5`5h7or_8h!{akAl`zw4RI%;ZmCEA=zSNc#91bDMDvQO#9kJc|4IW zzq$`!$wy-4>E1+nDj6#8jz&5|WtG0Fv+dbXs!w2}Y6KNVVro~gHxgYVVm;xcQJR1tG_jIC(bgWgSgmbW>zisC)Rtvx zTcEw8rmaI=)}pqy1p>{j9jd>vBU?u-C8F_Iw^vVCdlu`9r6S!iEvy@b<}6g%){2Fu z)r(;CU#P9Uv7x1=$*2rgQ&hz8@WH4c9PjIlY9bXhn*&{=)rES3NxkE1@kGMdqas4tMdy@7V$n!U1KO)4yR|Yr{wWK^@w6w%XB}l-Nxa1fv8f}yL*%vUAxq(KbDdwcO<2x`DrrX`cHIFQ!H0Mc|cRo07_CeiaFu}C@+ zjFxHrT1X$xYqext#8h@o>e}qMU^GDuYpD>aM)w(hWDLKa*Eswzb?rCqItQkXZv?v&aYp<$*AEA2qa8SeEru65(rOku5==R$Vcr+$IQB*e+!8V<`VEB; zJ&#%V1f9PB#}>|SmGPO(;}wD;usKBF{R)Gk-;iLVHi{SNbnCuB5tDSB_a+RAz^)0Q zdKBj=AKw#?;>K-D&nP}sFSim!ziqKF>f;tG8x;Na$BtVs1`L{_-wN5wc{`B}ia0fk zAg74agkiZsc8DXHd}KMkUO?Uk*)3!_&kNjw8Nnm2M27cP7T#m#2*@8Fhx6%y6)b)8 zaNlJFkJyR~`-`3<;dY9rh0-%5!M7$dZmk{#z7pm143_T(ywb)``z(LpE!PO}CX7FO z0yk^oSAbSv{cizz!nB|IDR1GFe+T#hTlpuzc|XTMejZ3To}@_Vty7V){6!K)g7+=F z)3f+nk+uAbFW$!6!%H;x(+0mJ4FA-Hk}17|9lo%x5pUYNw9w(a37eSM>+Asz`dq^dbfi8@q8QZ1-^fRB+fJW_i)Oa`n}L! zh4NRRf1z342)q-W!tta2mB5e9kObeg5bpxM9sF}m{x!gFH1!ptKQ{v3^DsOSc9H*E zz^iTcJOsSehCc=T%lVRiwjloq@TO6Hlf`S4x8a9?TlN>i{!fADLw=EIPciI#96NQs z_n|&7;1IU-d`Cvy2b}(!H2Kd4UV#4LQIzEu0ly37b4>d$1%9Q?-U#pxI1%5Gk$*Md z1q&p>H#)?5m*Cx*wdW4tPvC(dXFkjC2cEF$<2%rm;6G}X?*eXb-%G$t(cc_f%JcO7 zCG#lzEY1MF)>i-Lfph%@fWCZDhs@7# z&A7sp=Y7dB_}gxvHvW0QFR+dO1;DfZH$^N3{-lln3gCx<^ZgL@g@BJ>e69I$HSnlye7*?0 z4&$*H_K^P;;4j+r-3@%DZTxlux5mFnE*4J#Z$_A-+Qedjbm5doxpzOc)Jt(%X6Q;W5SlDr&0~3deub8xZzjv(jAZY z)dfENgo6`I0^b0DiO=90v{(los}sd98)88D937kG_Er%}rc>#@t}dtyYxvoM{yPaZ z-K&OhUer?9kcZ=HcQoD^jH+QgfX9iYuU}vzo4}iNEsRQz%b|9mEov~C46adeBu}mp zT}d2-)No&K?;42MFxV7Hk6~5S`nHazO!_CSXvfgb2eY8rmJA?&@{nv93> zbC2b*WIW0rg(UjYJgZhWG&TBbRa_rbp$c9l7&irKZ!i+e7A_ENE2=6R)pozy*4C&t zs*BVLi`3NAXcBQ@P%&<-vS@pgT4jnfuTXU*I=`y=+uO~4IF7-!{563H>Az~p+EXPG zNo=eU7{A6Q{IjW`~Fjcj^uBM|#^#>XnTiE037}RWCQxjU!hUSfJNgFKJol6nXdz-e}Y*5n@vj=b+QehQ#w_^vcv7=LVGe;F&0cyOwT*Ct4#n#_G}Tvv&dXrQ&K& zFc!vzNAI5v!nlK}J|@P`M64>>#ySTkN;q3&uPKQ-;=T5k8RpZEku&GG`5TjE7nw@v zNq;_G@B#F#sv2Fb|Byz-FHb@}nq9wY&G|$euB0XBX1f}{J<d zuP2!55x(%67=#U&P8ubvwPXsvNE?HwD8uPA=u1R#oK9=~NU=!qI>@K>n9C<`Rz@-5 zOC+`IQYw7*e0DX~tHw({OZ^jOyd_%oqcJ17Wl$i zXJ0p#>R=2bZ=w3#r&ZM1nZ(35G2Xsed32DKB^mC(&EsDgW`d8q5o{L(&*f<#b8NE4 zPDS8faKXK@$;b2D5DL6DK5lCmK97ixcwHaQ@sEP9)uaLF`#AFQ8|;tp-9GE(`QD98 z7Me7p}>1>`~CRv<6KMTmS`px29g z0XGzI?`PFZI^#-2zC~c3_Xnlmn~%J`UZA2Ikv8}d`JQ1Vkh_qlKAzrL#xrmfkv33X zaQ_1aw!;c+1LM_*79aOaEz zz9PikR-uiL=T941y!R^J$=C>1)@Sm~H|?oHNAZ=470AbU&N#kB=qTQ8Si#~Wq%T`x v^J_wQ(MT@{7a+2q3lVv -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -void RV32I_RET__I_32_1(){ /* RET */ - riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_RET__I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SUB_RRR_I_32_1(int r3,int r1,int r2){ /* SUB */ - riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SUB_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_MV_RR_I_32_1(int r0,int r1){ /* MV */ - riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_MV_RR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_MV_RI_I_32_1(int r3,int i1){ /* MV */ - riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_MV_RI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SLLI_RRI_I_32_1(int r3,int r1,int i0){ /* SL */ - riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SLLI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SLL_RRR_I_32_1(int r3,int r1,int r2){ /* SL */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SLL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32M_MUL_RRR_I_32_1(int r3,int r1,int r2){ /* MUL */ - riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32M_MUL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_ADDI_RRI_I_32_1(int r1,int r0,int i0){ /* ADD */ - riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_ADDI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_ADD_RRR_I_32_1(int r3,int r1,int r2){ /* ADD */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_ADD_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_LB_RRI_I_8_1(int r3,int r1,int i1){ /* R */ - riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_LB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void RV32I_LH_RRI_I_16_1(int r3,int r1,int i1){ /* R */ - riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_LH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void RV32I_LW_RRI_I_32_1(int r3,int r1,int i1){ /* R */ - riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_LW_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SRLI_RRI_I_32_1(int r3,int r1,int i0){ /* SR */ - riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SRLI_RRI_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SRL_RRR_I_32_1(int r3,int r1,int r2){ /* SR */ - riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SRL_RRR_I_32_1\n", h2_asm_pc); -#endif -} -void RV32I_SB_RRI_I_8_1(int r1,int r2,int i1){ /* W */ - riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SB_RRI_I_8_1\n", h2_asm_pc); -#endif -} -void RV32I_SH_RRI_I_16_1(int r1,int r2,int i1){ /* W */ - riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SH_RRI_I_16_1\n", h2_asm_pc); -#endif -} -void RV32I_SW_RRI_I_32_1(int r1,int r2,int i1){ /* W */ - riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); -#ifdef H2_DEBUG_INSN -printf("%p : RV32I_SW_RRI_I_32_1\n", h2_asm_pc); -#endif -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -/* -*- c -*- */ -// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/mesa/math/m_matrix.c -#include -#include -#include -#include -#define T 4 -typedef int d_t; -typedef d_t matrix_t [T][T]; -typedef d_t vector_t [T]; -typedef d_t (*pifvv)(vector_t, vector_t); - -pifvv genVectorMatrixProduct(pifvv ptr, matrix_t m) -{ - /* Code Generation of 5 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t o = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0007 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0008 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0009 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0010 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0011 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0012 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0013 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0014 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0015 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0016 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0017 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0018 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0019 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0020 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0021 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0022 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0023 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0024 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0025 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0026 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0027 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0028 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0029 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0030 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0031 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0032 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0033 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0034 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0035 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0036 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0037 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0038 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0039 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0040 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0041 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0042 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0043 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0044 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0045 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0046 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0047 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0048 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0049 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0050 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0051 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0052 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0053 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0054 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0055 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0056 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0057 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0058 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0059 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0060 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0061 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0062 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0063 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0064 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0065 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0066 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0067 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0068 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0069 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0070 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0071 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0072 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0073 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0074 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0075 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0076 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0077 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0078 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0079 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0080 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0081 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0082 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0083 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xF1F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp0000 = riscv_genMUL_4(tmp0000, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0001 = riscv_genADD_3(tmp0001, o, tmp0000); - if (!tmp0001.dontFree) h2_freeReg(tmp0000.regNro); - tmp0002 = riscv_genMUL_4(tmp0002, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0003 = riscv_genADD_3(tmp0003, i, tmp0002); - if (!tmp0003.dontFree) h2_freeReg(tmp0002.regNro); - tmp0004 = riscv_genR_3(tmp0004, tmp0003, immValueZero); - tmp0005 = riscv_genMUL_4(tmp0005, tmp0004, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][0]))}, immValueZero); - if (!tmp0005.dontFree) h2_freeReg(tmp0004.regNro); - tmp0006 = riscv_genMUL_4(tmp0006, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0007 = riscv_genADD_3(tmp0007, i, tmp0006); - if (!tmp0007.dontFree) h2_freeReg(tmp0006.regNro); - tmp0008 = riscv_genR_3(tmp0008, tmp0007, immValueZero); - tmp0009 = riscv_genMUL_4(tmp0009, tmp0008, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][0]))}, immValueZero); - if (!tmp0009.dontFree) h2_freeReg(tmp0008.regNro); - tmp0010 = riscv_genADD_3(tmp0010, tmp0005, tmp0009); - if (!tmp0010.dontFree) h2_freeReg(tmp0005.regNro); - if (!tmp0010.dontFree) h2_freeReg(tmp0009.regNro); - tmp0011 = riscv_genMUL_4(tmp0011, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0012 = riscv_genADD_3(tmp0012, i, tmp0011); - if (!tmp0012.dontFree) h2_freeReg(tmp0011.regNro); - tmp0013 = riscv_genR_3(tmp0013, tmp0012, immValueZero); - tmp0014 = riscv_genMUL_4(tmp0014, tmp0013, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][0]))}, immValueZero); - if (!tmp0014.dontFree) h2_freeReg(tmp0013.regNro); - tmp0015 = riscv_genADD_3(tmp0015, tmp0010, tmp0014); - if (!tmp0015.dontFree) h2_freeReg(tmp0010.regNro); - if (!tmp0015.dontFree) h2_freeReg(tmp0014.regNro); - tmp0016 = riscv_genMUL_4(tmp0016, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0017 = riscv_genADD_3(tmp0017, i, tmp0016); - if (!tmp0017.dontFree) h2_freeReg(tmp0016.regNro); - tmp0018 = riscv_genR_3(tmp0018, tmp0017, immValueZero); - tmp0019 = riscv_genMUL_4(tmp0019, tmp0018, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][0]))}, immValueZero); - if (!tmp0019.dontFree) h2_freeReg(tmp0018.regNro); - tmp0020 = riscv_genADD_3(tmp0020, tmp0015, tmp0019); - if (!tmp0020.dontFree) h2_freeReg(tmp0015.regNro); - if (!tmp0020.dontFree) h2_freeReg(tmp0019.regNro); - riscv_genW_3(tmp0001, tmp0020, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0021 = riscv_genMUL_4(tmp0021, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0022 = riscv_genADD_3(tmp0022, o, tmp0021); - if (!tmp0022.dontFree) h2_freeReg(tmp0021.regNro); - tmp0023 = riscv_genMUL_4(tmp0023, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0024 = riscv_genADD_3(tmp0024, i, tmp0023); - if (!tmp0024.dontFree) h2_freeReg(tmp0023.regNro); - tmp0025 = riscv_genR_3(tmp0025, tmp0024, immValueZero); - tmp0026 = riscv_genMUL_4(tmp0026, tmp0025, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][1]))}, immValueZero); - if (!tmp0026.dontFree) h2_freeReg(tmp0025.regNro); - tmp0027 = riscv_genMUL_4(tmp0027, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0028 = riscv_genADD_3(tmp0028, i, tmp0027); - if (!tmp0028.dontFree) h2_freeReg(tmp0027.regNro); - tmp0029 = riscv_genR_3(tmp0029, tmp0028, immValueZero); - tmp0030 = riscv_genMUL_4(tmp0030, tmp0029, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][1]))}, immValueZero); - if (!tmp0030.dontFree) h2_freeReg(tmp0029.regNro); - tmp0031 = riscv_genADD_3(tmp0031, tmp0026, tmp0030); - if (!tmp0031.dontFree) h2_freeReg(tmp0026.regNro); - if (!tmp0031.dontFree) h2_freeReg(tmp0030.regNro); - tmp0032 = riscv_genMUL_4(tmp0032, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0033 = riscv_genADD_3(tmp0033, i, tmp0032); - if (!tmp0033.dontFree) h2_freeReg(tmp0032.regNro); - tmp0034 = riscv_genR_3(tmp0034, tmp0033, immValueZero); - tmp0035 = riscv_genMUL_4(tmp0035, tmp0034, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][1]))}, immValueZero); - if (!tmp0035.dontFree) h2_freeReg(tmp0034.regNro); - tmp0036 = riscv_genADD_3(tmp0036, tmp0031, tmp0035); - if (!tmp0036.dontFree) h2_freeReg(tmp0031.regNro); - if (!tmp0036.dontFree) h2_freeReg(tmp0035.regNro); - tmp0037 = riscv_genMUL_4(tmp0037, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0038 = riscv_genADD_3(tmp0038, i, tmp0037); - if (!tmp0038.dontFree) h2_freeReg(tmp0037.regNro); - tmp0039 = riscv_genR_3(tmp0039, tmp0038, immValueZero); - tmp0040 = riscv_genMUL_4(tmp0040, tmp0039, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][1]))}, immValueZero); - if (!tmp0040.dontFree) h2_freeReg(tmp0039.regNro); - tmp0041 = riscv_genADD_3(tmp0041, tmp0036, tmp0040); - if (!tmp0041.dontFree) h2_freeReg(tmp0036.regNro); - if (!tmp0041.dontFree) h2_freeReg(tmp0040.regNro); - riscv_genW_3(tmp0022, tmp0041, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0042 = riscv_genMUL_4(tmp0042, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0043 = riscv_genADD_3(tmp0043, o, tmp0042); - if (!tmp0043.dontFree) h2_freeReg(tmp0042.regNro); - tmp0044 = riscv_genMUL_4(tmp0044, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0045 = riscv_genADD_3(tmp0045, i, tmp0044); - if (!tmp0045.dontFree) h2_freeReg(tmp0044.regNro); - tmp0046 = riscv_genR_3(tmp0046, tmp0045, immValueZero); - tmp0047 = riscv_genMUL_4(tmp0047, tmp0046, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][2]))}, immValueZero); - if (!tmp0047.dontFree) h2_freeReg(tmp0046.regNro); - tmp0048 = riscv_genMUL_4(tmp0048, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0049 = riscv_genADD_3(tmp0049, i, tmp0048); - if (!tmp0049.dontFree) h2_freeReg(tmp0048.regNro); - tmp0050 = riscv_genR_3(tmp0050, tmp0049, immValueZero); - tmp0051 = riscv_genMUL_4(tmp0051, tmp0050, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][2]))}, immValueZero); - if (!tmp0051.dontFree) h2_freeReg(tmp0050.regNro); - tmp0052 = riscv_genADD_3(tmp0052, tmp0047, tmp0051); - if (!tmp0052.dontFree) h2_freeReg(tmp0047.regNro); - if (!tmp0052.dontFree) h2_freeReg(tmp0051.regNro); - tmp0053 = riscv_genMUL_4(tmp0053, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0054 = riscv_genADD_3(tmp0054, i, tmp0053); - if (!tmp0054.dontFree) h2_freeReg(tmp0053.regNro); - tmp0055 = riscv_genR_3(tmp0055, tmp0054, immValueZero); - tmp0056 = riscv_genMUL_4(tmp0056, tmp0055, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][2]))}, immValueZero); - if (!tmp0056.dontFree) h2_freeReg(tmp0055.regNro); - tmp0057 = riscv_genADD_3(tmp0057, tmp0052, tmp0056); - if (!tmp0057.dontFree) h2_freeReg(tmp0052.regNro); - if (!tmp0057.dontFree) h2_freeReg(tmp0056.regNro); - tmp0058 = riscv_genMUL_4(tmp0058, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0059 = riscv_genADD_3(tmp0059, i, tmp0058); - if (!tmp0059.dontFree) h2_freeReg(tmp0058.regNro); - tmp0060 = riscv_genR_3(tmp0060, tmp0059, immValueZero); - tmp0061 = riscv_genMUL_4(tmp0061, tmp0060, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][2]))}, immValueZero); - if (!tmp0061.dontFree) h2_freeReg(tmp0060.regNro); - tmp0062 = riscv_genADD_3(tmp0062, tmp0057, tmp0061); - if (!tmp0062.dontFree) h2_freeReg(tmp0057.regNro); - if (!tmp0062.dontFree) h2_freeReg(tmp0061.regNro); - riscv_genW_3(tmp0043, tmp0062, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp0063 = riscv_genMUL_4(tmp0063, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0064 = riscv_genADD_3(tmp0064, o, tmp0063); - if (!tmp0064.dontFree) h2_freeReg(tmp0063.regNro); - tmp0065 = riscv_genMUL_4(tmp0065, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0066 = riscv_genADD_3(tmp0066, i, tmp0065); - if (!tmp0066.dontFree) h2_freeReg(tmp0065.regNro); - tmp0067 = riscv_genR_3(tmp0067, tmp0066, immValueZero); - tmp0068 = riscv_genMUL_4(tmp0068, tmp0067, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[0][3]))}, immValueZero); - if (!tmp0068.dontFree) h2_freeReg(tmp0067.regNro); - tmp0069 = riscv_genMUL_4(tmp0069, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0070 = riscv_genADD_3(tmp0070, i, tmp0069); - if (!tmp0070.dontFree) h2_freeReg(tmp0069.regNro); - tmp0071 = riscv_genR_3(tmp0071, tmp0070, immValueZero); - tmp0072 = riscv_genMUL_4(tmp0072, tmp0071, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[1][3]))}, immValueZero); - if (!tmp0072.dontFree) h2_freeReg(tmp0071.regNro); - tmp0073 = riscv_genADD_3(tmp0073, tmp0068, tmp0072); - if (!tmp0073.dontFree) h2_freeReg(tmp0068.regNro); - if (!tmp0073.dontFree) h2_freeReg(tmp0072.regNro); - tmp0074 = riscv_genMUL_4(tmp0074, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(2)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0075 = riscv_genADD_3(tmp0075, i, tmp0074); - if (!tmp0075.dontFree) h2_freeReg(tmp0074.regNro); - tmp0076 = riscv_genR_3(tmp0076, tmp0075, immValueZero); - tmp0077 = riscv_genMUL_4(tmp0077, tmp0076, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[2][3]))}, immValueZero); - if (!tmp0077.dontFree) h2_freeReg(tmp0076.regNro); - tmp0078 = riscv_genADD_3(tmp0078, tmp0073, tmp0077); - if (!tmp0078.dontFree) h2_freeReg(tmp0073.regNro); - if (!tmp0078.dontFree) h2_freeReg(tmp0077.regNro); - tmp0079 = riscv_genMUL_4(tmp0079, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(3)}, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((1 * 32) / 8)}, immValueZero); - tmp0080 = riscv_genADD_3(tmp0080, i, tmp0079); - if (!tmp0080.dontFree) h2_freeReg(tmp0079.regNro); - tmp0081 = riscv_genR_3(tmp0081, tmp0080, immValueZero); - tmp0082 = riscv_genMUL_4(tmp0082, tmp0081, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((m[3][3]))}, immValueZero); - if (!tmp0082.dontFree) h2_freeReg(tmp0081.regNro); - tmp0083 = riscv_genADD_3(tmp0083, tmp0078, tmp0082); - if (!tmp0083.dontFree) h2_freeReg(tmp0078.regNro); - if (!tmp0083.dontFree) h2_freeReg(tmp0082.regNro); - riscv_genW_3(tmp0064, tmp0083, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return ptr; -} - -d_t VectorMatrixProductUnrolled (vector_t o, vector_t i, matrix_t m) -{ - o[0] = i[0]*m[0][0] + i[1]*m[1][0] + i[2]*m[2][0] + i[3]*m[3][0]; - o[1] = i[0]*m[0][1] + i[1]*m[1][1] + i[2]*m[2][1] + i[3]*m[3][1]; - o[2] = i[0]*m[0][2] + i[1]*m[1][2] + i[2]*m[2][2] + i[3]*m[3][2]; - o[3] = i[0]*m[0][3] + i[1]*m[1][3] + i[2]*m[2][3] + i[3]*m[3][3]; - return o[3]; -} - -#if 0 // What the binary code should be with a translation matrix -d_t VectorMatrixProductUnrolledSR(vector_t o, vector_t i, matrix_t m) -{ - - o[0] = m[0][0] * i[0] + + m[3][0] * i[3]; - o[1] = m[1][1] * i[1] + + m[3][1] * i[3]; - o[2] = m[2][2] * i[2] + m[3][2] * i[3]; - o[3] = + i[3]; - return o[3]; -} -#endif -d_t VectorMatrixProduct (vector_t o, vector_t i, matrix_t m) -{ - for (int column = 0; column < T; column++) - { - o[column] = 0; - for (int line = 0; line < T; line++) - { - o[column] += i[line] * m[line][column]; - - } - } - return o[3]; -} - - -int VectorMatrixProductCount(matrix_t mat) -{ - int op = 0; - for (int column = 0; column < T; column++) - { - for (int line = 0; line < T; line++) - { - switch (mat[line][column]) - { - case 0 : op += 0; break; - case 1 : op += 1; break; - default: op += 2; break; - } - } - } - return op; -} - - -void printMatrix (matrix_t m, char msg[]) -{ - printf ("%s:\n", msg); - for (int column = 0; column < T; column++) - { - for (int line = 0; line < T; line++) - { - printf ("%4d ", m[line][column]); - } - printf ("\n"); - } - printf ("\n"); -} - -void printVector (vector_t v, char msg[]) -{ - for (int i = 0; i < T; i++) - printf ("%4d ", v[i]); - printf ("%s\n", msg); -} - -bool vectorCompare(vector_t ref[], vector_t other[], char * msg, int doPrint, int nVector) -{ - int has_differences = false; - for (int line = 0; line < nVector; line++) - for (int i = 0; i < T; i++) - { - if (ref[line][i] != other[line][i]) - has_differences = true; - if (doPrint) - printf("%4d ", other[line][i]); - } - /* printf("%s : ", msg); */ - /* printf(" %s\n", (has_differences)?"NOT OK":"OK"); */ - return has_differences; -} - -int main (int argc, char *argv[]) -{ - matrix_t m; - char *matrixName; - // vector_t in0 = {1, 2, 3, 4}, in1 = {5, 6, 7, 8}; - vector_t *out, *cout, *in; - uint64_t timeGeneral, timeCompilette; - pifvv vmProduct; - int tmp, doPrint, nXperiment; - unsigned long acc; - bool resultValid; - - if (argc != 19) - { - printf ("Not enough arguments %d\n", argc); - printf ("VectorMatrix ExperimentNumber MatrixName M11 M12 ... M44\n"); - exit (-1); - } - doPrint = 0; - acc = 0; - nXperiment = atoi (argv[1]); - matrixName = argv[2]; - for (int line = 0; line < 4; line++) - for (int column = 0; column < 4; column++) - { - m[line][column] = atoi (argv[3 + line*4+column]); - } -#ifdef VERBOSE - printMatrix(m, matrixName); -#endif - - in = calloc(nXperiment, sizeof (vector_t)); - out = calloc(nXperiment, sizeof (vector_t)); - cout = calloc(nXperiment, sizeof (vector_t)); - - for (int line = 0; line < nXperiment; line++) - for (int column = 0; column < 4; column++) - in[line][column] = random () % 1000; - - tmp = VectorMatrixProductCount (m); - printf("Operation count Matrix %s : %d theoretical speedup %.1f\n", matrixName, tmp, (0==tmp)?32:32.0/tmp); - -// Repeat one instruction and count ticks -#define DO(INSN, REPEAT, TIME) {uint64_t tickCount = h2_getticks();for (int i = 0; i < REPEAT; i++) INSN; TIME = h2_getticks() - tickCount;} - -#ifdef VERBOSE - printVector (in[0], "Input vector #0"); -#endif - - acc += VectorMatrixProduct (out[0], in[0], m); /* Cold start */ - DO(acc += VectorMatrixProduct (out[i], in[i], m), nXperiment, timeGeneral) - -#ifdef VERBOSE - printVector (out[0], "Output vector #0 (general)"); -#endif - -#if 0 // Possible test with a source level unrolled version - uint64_t timeUnrolled; - vector_t uout0, uout1; - acc += VectorMatrixProductUnrolled (uout0, in0, m); - DO(acc += VectorMatrixProductUnrolled (uout1, in1, m), nXperiment, timeUnrolled); - vectorCompare(out1, uout1, "Unrolled out0", doPrint); -#endif - - vmProduct = (pifvv) h2_malloc(1024); - vmProduct = genVectorMatrixProduct (vmProduct, m); - acc += vmProduct (cout[0], in[0]); - DO(acc += vmProduct (cout[i], in[i]), nXperiment, timeCompilette); - -#ifdef VERBOSE - printVector (cout[0], "Output vector #0 (compilette)"); -#endif - - resultValid = vectorCompare(out, cout, "Compilette", doPrint, nXperiment); - - printf ("%s;%d;%lu;%lu;%lld;%d;%s\n", - matrixName, nXperiment, - timeGeneral, timeCompilette, - h2_codeGenTime, h2_insnGenerated, - resultValid?"true":"false"); - return resultValid; -} diff --git a/HybroGen/IsaDescription.interp b/HybroGen/IsaDescription.interp deleted file mode 100644 index c1157f7..0000000 --- a/HybroGen/IsaDescription.interp +++ /dev/null @@ -1,58 +0,0 @@ -token literal names: -null -'ARCH' -'|' -'[' -']' -'i' -'u' -'f' -null -null -null -null -null -':' -null - -token symbolic names: -null -null -null -null -null -null -null -null -WS -COMMENT -INT -NAME -NEWLINE -SEMICOL -CINLINE - -rule names: -isadescription -headerlines -archline -isalines -commentline -isaline -emptyline -bindescr -binelem -binvalue -regbin -expbin -asmdescr -extname -arith -opname -regName -semname -reglist - - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 16, 133, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 6, 3, 47, 10, 3, 13, 3, 14, 3, 48, 3, 4, 3, 4, 3, 4, 6, 4, 54, 10, 4, 13, 4, 14, 4, 55, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 7, 5, 63, 10, 5, 12, 5, 14, 5, 66, 11, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 6, 9, 78, 10, 9, 13, 9, 14, 9, 79, 3, 10, 3, 10, 3, 10, 5, 10, 85, 10, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 94, 10, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 103, 10, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 5, 14, 114, 10, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 7, 20, 128, 10, 20, 12, 20, 14, 20, 131, 11, 20, 3, 20, 2, 2, 21, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 2, 3, 3, 2, 7, 9, 2, 127, 2, 40, 3, 2, 2, 2, 4, 46, 3, 2, 2, 2, 6, 50, 3, 2, 2, 2, 8, 64, 3, 2, 2, 2, 10, 67, 3, 2, 2, 2, 12, 69, 3, 2, 2, 2, 14, 74, 3, 2, 2, 2, 16, 77, 3, 2, 2, 2, 18, 84, 3, 2, 2, 2, 20, 86, 3, 2, 2, 2, 22, 88, 3, 2, 2, 2, 24, 97, 3, 2, 2, 2, 26, 106, 3, 2, 2, 2, 28, 115, 3, 2, 2, 2, 30, 117, 3, 2, 2, 2, 32, 119, 3, 2, 2, 2, 34, 121, 3, 2, 2, 2, 36, 123, 3, 2, 2, 2, 38, 125, 3, 2, 2, 2, 40, 41, 5, 4, 3, 2, 41, 42, 5, 8, 5, 2, 42, 3, 3, 2, 2, 2, 43, 47, 5, 10, 6, 2, 44, 47, 5, 6, 4, 2, 45, 47, 5, 14, 8, 2, 46, 43, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 46, 45, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 48, 49, 3, 2, 2, 2, 49, 5, 3, 2, 2, 2, 50, 51, 7, 3, 2, 2, 51, 53, 7, 13, 2, 2, 52, 54, 7, 12, 2, 2, 53, 52, 3, 2, 2, 2, 54, 55, 3, 2, 2, 2, 55, 53, 3, 2, 2, 2, 55, 56, 3, 2, 2, 2, 56, 57, 3, 2, 2, 2, 57, 58, 7, 14, 2, 2, 58, 7, 3, 2, 2, 2, 59, 63, 5, 10, 6, 2, 60, 63, 5, 14, 8, 2, 61, 63, 5, 12, 7, 2, 62, 59, 3, 2, 2, 2, 62, 60, 3, 2, 2, 2, 62, 61, 3, 2, 2, 2, 63, 66, 3, 2, 2, 2, 64, 62, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 9, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 67, 68, 7, 11, 2, 2, 68, 11, 3, 2, 2, 2, 69, 70, 5, 16, 9, 2, 70, 71, 7, 4, 2, 2, 71, 72, 5, 26, 14, 2, 72, 73, 7, 14, 2, 2, 73, 13, 3, 2, 2, 2, 74, 75, 7, 14, 2, 2, 75, 15, 3, 2, 2, 2, 76, 78, 5, 18, 10, 2, 77, 76, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 77, 3, 2, 2, 2, 79, 80, 3, 2, 2, 2, 80, 17, 3, 2, 2, 2, 81, 85, 5, 20, 11, 2, 82, 85, 5, 22, 12, 2, 83, 85, 5, 24, 13, 2, 84, 81, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 83, 3, 2, 2, 2, 85, 19, 3, 2, 2, 2, 86, 87, 7, 12, 2, 2, 87, 21, 3, 2, 2, 2, 88, 89, 7, 13, 2, 2, 89, 90, 7, 5, 2, 2, 90, 93, 7, 12, 2, 2, 91, 92, 7, 15, 2, 2, 92, 94, 7, 12, 2, 2, 93, 91, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 96, 7, 6, 2, 2, 96, 23, 3, 2, 2, 2, 97, 98, 7, 16, 2, 2, 98, 99, 7, 5, 2, 2, 99, 102, 7, 12, 2, 2, 100, 101, 7, 15, 2, 2, 101, 103, 7, 12, 2, 2, 102, 100, 3, 2, 2, 2, 102, 103, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 105, 7, 6, 2, 2, 105, 25, 3, 2, 2, 2, 106, 107, 5, 28, 15, 2, 107, 108, 5, 30, 16, 2, 108, 109, 7, 12, 2, 2, 109, 110, 7, 12, 2, 2, 110, 111, 5, 36, 19, 2, 111, 113, 5, 32, 17, 2, 112, 114, 5, 38, 20, 2, 113, 112, 3, 2, 2, 2, 113, 114, 3, 2, 2, 2, 114, 27, 3, 2, 2, 2, 115, 116, 7, 13, 2, 2, 116, 29, 3, 2, 2, 2, 117, 118, 9, 2, 2, 2, 118, 31, 3, 2, 2, 2, 119, 120, 7, 13, 2, 2, 120, 33, 3, 2, 2, 2, 121, 122, 7, 13, 2, 2, 122, 35, 3, 2, 2, 2, 123, 124, 7, 13, 2, 2, 124, 37, 3, 2, 2, 2, 125, 129, 5, 34, 18, 2, 126, 128, 5, 34, 18, 2, 127, 126, 3, 2, 2, 2, 128, 131, 3, 2, 2, 2, 129, 127, 3, 2, 2, 2, 129, 130, 3, 2, 2, 2, 130, 39, 3, 2, 2, 2, 131, 129, 3, 2, 2, 2, 13, 46, 48, 55, 62, 64, 79, 84, 93, 102, 113, 129] \ No newline at end of file diff --git a/HybroGen/IsaDescription.tokens b/HybroGen/IsaDescription.tokens deleted file mode 100644 index 2dcd920..0000000 --- a/HybroGen/IsaDescription.tokens +++ /dev/null @@ -1,22 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -T__4=5 -T__5=6 -T__6=7 -WS=8 -COMMENT=9 -INT=10 -NAME=11 -NEWLINE=12 -SEMICOL=13 -CINLINE=14 -'ARCH'=1 -'|'=2 -'['=3 -']'=4 -'i'=5 -'u'=6 -'f'=7 -':'=13 diff --git a/HybroGen/IsaDescriptionLexer.interp b/HybroGen/IsaDescriptionLexer.interp deleted file mode 100644 index 23a6756..0000000 --- a/HybroGen/IsaDescriptionLexer.interp +++ /dev/null @@ -1,59 +0,0 @@ -token literal names: -null -'ARCH' -'|' -'[' -']' -'i' -'u' -'f' -null -null -null -null -null -':' -null - -token symbolic names: -null -null -null -null -null -null -null -null -WS -COMMENT -INT -NAME -NEWLINE -SEMICOL -CINLINE - -rule names: -T__0 -T__1 -T__2 -T__3 -T__4 -T__5 -T__6 -WS -COMMENT -INT -NAME -NEWLINE -SEMICOL -CINLINE - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 16, 91, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 6, 9, 50, 10, 9, 13, 9, 14, 9, 51, 3, 9, 3, 9, 3, 10, 3, 10, 7, 10, 58, 10, 10, 12, 10, 14, 10, 61, 11, 10, 3, 10, 3, 10, 3, 11, 6, 11, 66, 10, 11, 13, 11, 14, 11, 67, 3, 12, 3, 12, 7, 12, 72, 10, 12, 12, 12, 14, 12, 75, 11, 12, 3, 13, 5, 13, 78, 10, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 6, 15, 86, 10, 15, 13, 15, 14, 15, 87, 3, 15, 3, 15, 3, 59, 2, 16, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 3, 2, 7, 4, 2, 11, 11, 34, 34, 3, 2, 50, 59, 4, 2, 67, 92, 99, 124, 7, 2, 48, 48, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 127, 127, 2, 96, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 3, 31, 3, 2, 2, 2, 5, 36, 3, 2, 2, 2, 7, 38, 3, 2, 2, 2, 9, 40, 3, 2, 2, 2, 11, 42, 3, 2, 2, 2, 13, 44, 3, 2, 2, 2, 15, 46, 3, 2, 2, 2, 17, 49, 3, 2, 2, 2, 19, 55, 3, 2, 2, 2, 21, 65, 3, 2, 2, 2, 23, 69, 3, 2, 2, 2, 25, 77, 3, 2, 2, 2, 27, 81, 3, 2, 2, 2, 29, 83, 3, 2, 2, 2, 31, 32, 7, 67, 2, 2, 32, 33, 7, 84, 2, 2, 33, 34, 7, 69, 2, 2, 34, 35, 7, 74, 2, 2, 35, 4, 3, 2, 2, 2, 36, 37, 7, 126, 2, 2, 37, 6, 3, 2, 2, 2, 38, 39, 7, 93, 2, 2, 39, 8, 3, 2, 2, 2, 40, 41, 7, 95, 2, 2, 41, 10, 3, 2, 2, 2, 42, 43, 7, 107, 2, 2, 43, 12, 3, 2, 2, 2, 44, 45, 7, 119, 2, 2, 45, 14, 3, 2, 2, 2, 46, 47, 7, 104, 2, 2, 47, 16, 3, 2, 2, 2, 48, 50, 9, 2, 2, 2, 49, 48, 3, 2, 2, 2, 50, 51, 3, 2, 2, 2, 51, 49, 3, 2, 2, 2, 51, 52, 3, 2, 2, 2, 52, 53, 3, 2, 2, 2, 53, 54, 8, 9, 2, 2, 54, 18, 3, 2, 2, 2, 55, 59, 7, 37, 2, 2, 56, 58, 11, 2, 2, 2, 57, 56, 3, 2, 2, 2, 58, 61, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 59, 57, 3, 2, 2, 2, 60, 62, 3, 2, 2, 2, 61, 59, 3, 2, 2, 2, 62, 63, 5, 25, 13, 2, 63, 20, 3, 2, 2, 2, 64, 66, 9, 3, 2, 2, 65, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 65, 3, 2, 2, 2, 67, 68, 3, 2, 2, 2, 68, 22, 3, 2, 2, 2, 69, 73, 9, 4, 2, 2, 70, 72, 9, 5, 2, 2, 71, 70, 3, 2, 2, 2, 72, 75, 3, 2, 2, 2, 73, 71, 3, 2, 2, 2, 73, 74, 3, 2, 2, 2, 74, 24, 3, 2, 2, 2, 75, 73, 3, 2, 2, 2, 76, 78, 7, 15, 2, 2, 77, 76, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 80, 7, 12, 2, 2, 80, 26, 3, 2, 2, 2, 81, 82, 7, 60, 2, 2, 82, 28, 3, 2, 2, 2, 83, 85, 7, 125, 2, 2, 84, 86, 10, 6, 2, 2, 85, 84, 3, 2, 2, 2, 86, 87, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 89, 3, 2, 2, 2, 89, 90, 7, 127, 2, 2, 90, 30, 3, 2, 2, 2, 9, 2, 51, 59, 67, 73, 77, 87, 3, 8, 2, 2] \ No newline at end of file diff --git a/HybroGen/IsaDescriptionLexer.py b/HybroGen/IsaDescriptionLexer.py deleted file mode 100644 index 1ace933..0000000 --- a/HybroGen/IsaDescriptionLexer.py +++ /dev/null @@ -1,92 +0,0 @@ -# Generated from IsaDescription.g4 by ANTLR 4.9.2 -from antlr4 import * -from io import StringIO -import sys -if sys.version_info[1] > 5: - from typing import TextIO -else: - from typing.io import TextIO - - -def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\20") - buf.write("[\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") - buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") - buf.write("\t\16\4\17\t\17\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3") - buf.write("\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\6\t\62\n\t\r\t\16\t") - buf.write("\63\3\t\3\t\3\n\3\n\7\n:\n\n\f\n\16\n=\13\n\3\n\3\n\3") - buf.write("\13\6\13B\n\13\r\13\16\13C\3\f\3\f\7\fH\n\f\f\f\16\fK") - buf.write("\13\f\3\r\5\rN\n\r\3\r\3\r\3\16\3\16\3\17\3\17\6\17V\n") - buf.write("\17\r\17\16\17W\3\17\3\17\3;\2\20\3\3\5\4\7\5\t\6\13\7") - buf.write("\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\3\2\7") - buf.write("\4\2\13\13\"\"\3\2\62;\4\2C\\c|\7\2\60\60\62;C\\aac|\3") - buf.write("\2\177\177\2`\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t") - buf.write("\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3") - buf.write("\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2") - buf.write("\2\2\2\33\3\2\2\2\2\35\3\2\2\2\3\37\3\2\2\2\5$\3\2\2\2") - buf.write("\7&\3\2\2\2\t(\3\2\2\2\13*\3\2\2\2\r,\3\2\2\2\17.\3\2") - buf.write("\2\2\21\61\3\2\2\2\23\67\3\2\2\2\25A\3\2\2\2\27E\3\2\2") - buf.write("\2\31M\3\2\2\2\33Q\3\2\2\2\35S\3\2\2\2\37 \7C\2\2 !\7") - buf.write("T\2\2!\"\7E\2\2\"#\7J\2\2#\4\3\2\2\2$%\7~\2\2%\6\3\2\2") - buf.write("\2&\'\7]\2\2\'\b\3\2\2\2()\7_\2\2)\n\3\2\2\2*+\7k\2\2") - buf.write("+\f\3\2\2\2,-\7w\2\2-\16\3\2\2\2./\7h\2\2/\20\3\2\2\2") - buf.write("\60\62\t\2\2\2\61\60\3\2\2\2\62\63\3\2\2\2\63\61\3\2\2") - buf.write("\2\63\64\3\2\2\2\64\65\3\2\2\2\65\66\b\t\2\2\66\22\3\2") - buf.write("\2\2\67;\7%\2\28:\13\2\2\298\3\2\2\2:=\3\2\2\2;<\3\2\2") - buf.write("\2;9\3\2\2\2<>\3\2\2\2=;\3\2\2\2>?\5\31\r\2?\24\3\2\2") - buf.write("\2@B\t\3\2\2A@\3\2\2\2BC\3\2\2\2CA\3\2\2\2CD\3\2\2\2D") - buf.write("\26\3\2\2\2EI\t\4\2\2FH\t\5\2\2GF\3\2\2\2HK\3\2\2\2IG") - buf.write("\3\2\2\2IJ\3\2\2\2J\30\3\2\2\2KI\3\2\2\2LN\7\17\2\2ML") - buf.write("\3\2\2\2MN\3\2\2\2NO\3\2\2\2OP\7\f\2\2P\32\3\2\2\2QR\7") - buf.write("<\2\2R\34\3\2\2\2SU\7}\2\2TV\n\6\2\2UT\3\2\2\2VW\3\2\2") - buf.write("\2WU\3\2\2\2WX\3\2\2\2XY\3\2\2\2YZ\7\177\2\2Z\36\3\2\2") - buf.write("\2\t\2\63;CIMW\3\b\2\2") - return buf.getvalue() - - -class IsaDescriptionLexer(Lexer): - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - - T__0 = 1 - T__1 = 2 - T__2 = 3 - T__3 = 4 - T__4 = 5 - T__5 = 6 - T__6 = 7 - WS = 8 - COMMENT = 9 - INT = 10 - NAME = 11 - NEWLINE = 12 - SEMICOL = 13 - CINLINE = 14 - - channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] - - modeNames = [ "DEFAULT_MODE" ] - - literalNames = [ "", - "'ARCH'", "'|'", "'['", "']'", "'i'", "'u'", "'f'", "':'" ] - - symbolicNames = [ "", - "WS", "COMMENT", "INT", "NAME", "NEWLINE", "SEMICOL", "CINLINE" ] - - ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", - "WS", "COMMENT", "INT", "NAME", "NEWLINE", "SEMICOL", - "CINLINE" ] - - grammarFileName = "IsaDescription.g4" - - def __init__(self, input=None, output:TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.9.2") - self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) - self._actions = None - self._predicates = None - - diff --git a/HybroGen/IsaDescriptionLexer.tokens b/HybroGen/IsaDescriptionLexer.tokens deleted file mode 100644 index 2dcd920..0000000 --- a/HybroGen/IsaDescriptionLexer.tokens +++ /dev/null @@ -1,22 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -T__4=5 -T__5=6 -T__6=7 -WS=8 -COMMENT=9 -INT=10 -NAME=11 -NEWLINE=12 -SEMICOL=13 -CINLINE=14 -'ARCH'=1 -'|'=2 -'['=3 -']'=4 -'i'=5 -'u'=6 -'f'=7 -':'=13 diff --git a/HybroGen/IsaDescriptionListener.py b/HybroGen/IsaDescriptionListener.py deleted file mode 100644 index f1a6b6f..0000000 --- a/HybroGen/IsaDescriptionListener.py +++ /dev/null @@ -1,183 +0,0 @@ -# Generated from IsaDescription.g4 by ANTLR 4.9.2 -from antlr4 import * -if __name__ is not None and "." in __name__: - from .IsaDescriptionParser import IsaDescriptionParser -else: - from IsaDescriptionParser import IsaDescriptionParser - -# This class defines a complete listener for a parse tree produced by IsaDescriptionParser. -class IsaDescriptionListener(ParseTreeListener): - - # Enter a parse tree produced by IsaDescriptionParser#isadescription. - def enterIsadescription(self, ctx:IsaDescriptionParser.IsadescriptionContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#isadescription. - def exitIsadescription(self, ctx:IsaDescriptionParser.IsadescriptionContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#headerlines. - def enterHeaderlines(self, ctx:IsaDescriptionParser.HeaderlinesContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#headerlines. - def exitHeaderlines(self, ctx:IsaDescriptionParser.HeaderlinesContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#archline. - def enterArchline(self, ctx:IsaDescriptionParser.ArchlineContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#archline. - def exitArchline(self, ctx:IsaDescriptionParser.ArchlineContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#isalines. - def enterIsalines(self, ctx:IsaDescriptionParser.IsalinesContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#isalines. - def exitIsalines(self, ctx:IsaDescriptionParser.IsalinesContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#commentline. - def enterCommentline(self, ctx:IsaDescriptionParser.CommentlineContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#commentline. - def exitCommentline(self, ctx:IsaDescriptionParser.CommentlineContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#isaline. - def enterIsaline(self, ctx:IsaDescriptionParser.IsalineContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#isaline. - def exitIsaline(self, ctx:IsaDescriptionParser.IsalineContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#emptyline. - def enterEmptyline(self, ctx:IsaDescriptionParser.EmptylineContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#emptyline. - def exitEmptyline(self, ctx:IsaDescriptionParser.EmptylineContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#bindescr. - def enterBindescr(self, ctx:IsaDescriptionParser.BindescrContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#bindescr. - def exitBindescr(self, ctx:IsaDescriptionParser.BindescrContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#binelem. - def enterBinelem(self, ctx:IsaDescriptionParser.BinelemContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#binelem. - def exitBinelem(self, ctx:IsaDescriptionParser.BinelemContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#binvalue. - def enterBinvalue(self, ctx:IsaDescriptionParser.BinvalueContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#binvalue. - def exitBinvalue(self, ctx:IsaDescriptionParser.BinvalueContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#regbin. - def enterRegbin(self, ctx:IsaDescriptionParser.RegbinContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#regbin. - def exitRegbin(self, ctx:IsaDescriptionParser.RegbinContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#expbin. - def enterExpbin(self, ctx:IsaDescriptionParser.ExpbinContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#expbin. - def exitExpbin(self, ctx:IsaDescriptionParser.ExpbinContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#asmdescr. - def enterAsmdescr(self, ctx:IsaDescriptionParser.AsmdescrContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#asmdescr. - def exitAsmdescr(self, ctx:IsaDescriptionParser.AsmdescrContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#extname. - def enterExtname(self, ctx:IsaDescriptionParser.ExtnameContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#extname. - def exitExtname(self, ctx:IsaDescriptionParser.ExtnameContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#arith. - def enterArith(self, ctx:IsaDescriptionParser.ArithContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#arith. - def exitArith(self, ctx:IsaDescriptionParser.ArithContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#opname. - def enterOpname(self, ctx:IsaDescriptionParser.OpnameContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#opname. - def exitOpname(self, ctx:IsaDescriptionParser.OpnameContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#regName. - def enterRegName(self, ctx:IsaDescriptionParser.RegNameContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#regName. - def exitRegName(self, ctx:IsaDescriptionParser.RegNameContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#semname. - def enterSemname(self, ctx:IsaDescriptionParser.SemnameContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#semname. - def exitSemname(self, ctx:IsaDescriptionParser.SemnameContext): - pass - - - # Enter a parse tree produced by IsaDescriptionParser#reglist. - def enterReglist(self, ctx:IsaDescriptionParser.ReglistContext): - pass - - # Exit a parse tree produced by IsaDescriptionParser#reglist. - def exitReglist(self, ctx:IsaDescriptionParser.ReglistContext): - pass - - - -del IsaDescriptionParser \ No newline at end of file diff --git a/HybroGen/IsaDescriptionParser.py b/HybroGen/IsaDescriptionParser.py deleted file mode 100644 index cd79c81..0000000 --- a/HybroGen/IsaDescriptionParser.py +++ /dev/null @@ -1,1179 +0,0 @@ -# Generated from IsaDescription.g4 by ANTLR 4.9.2 -# encoding: utf-8 -from antlr4 import * -from io import StringIO -import sys -if sys.version_info[1] > 5: - from typing import TextIO -else: - from typing.io import TextIO - -def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\20") - buf.write("\u0085\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") - buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") - buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") - buf.write("\4\24\t\24\3\2\3\2\3\2\3\3\3\3\3\3\6\3/\n\3\r\3\16\3\60") - buf.write("\3\4\3\4\3\4\6\4\66\n\4\r\4\16\4\67\3\4\3\4\3\5\3\5\3") - buf.write("\5\7\5?\n\5\f\5\16\5B\13\5\3\6\3\6\3\7\3\7\3\7\3\7\3\7") - buf.write("\3\b\3\b\3\t\6\tN\n\t\r\t\16\tO\3\n\3\n\3\n\5\nU\n\n\3") - buf.write("\13\3\13\3\f\3\f\3\f\3\f\3\f\5\f^\n\f\3\f\3\f\3\r\3\r") - buf.write("\3\r\3\r\3\r\5\rg\n\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16") - buf.write("\3\16\3\16\5\16r\n\16\3\17\3\17\3\20\3\20\3\21\3\21\3") - buf.write("\22\3\22\3\23\3\23\3\24\3\24\7\24\u0080\n\24\f\24\16\24") - buf.write("\u0083\13\24\3\24\2\2\25\2\4\6\b\n\f\16\20\22\24\26\30") - buf.write("\32\34\36 \"$&\2\3\3\2\7\t\2\177\2(\3\2\2\2\4.\3\2\2\2") - buf.write("\6\62\3\2\2\2\b@\3\2\2\2\nC\3\2\2\2\fE\3\2\2\2\16J\3\2") - buf.write("\2\2\20M\3\2\2\2\22T\3\2\2\2\24V\3\2\2\2\26X\3\2\2\2\30") - buf.write("a\3\2\2\2\32j\3\2\2\2\34s\3\2\2\2\36u\3\2\2\2 w\3\2\2") - buf.write("\2\"y\3\2\2\2${\3\2\2\2&}\3\2\2\2()\5\4\3\2)*\5\b\5\2") - buf.write("*\3\3\2\2\2+/\5\n\6\2,/\5\6\4\2-/\5\16\b\2.+\3\2\2\2.") - buf.write(",\3\2\2\2.-\3\2\2\2/\60\3\2\2\2\60.\3\2\2\2\60\61\3\2") - buf.write("\2\2\61\5\3\2\2\2\62\63\7\3\2\2\63\65\7\r\2\2\64\66\7") - buf.write("\f\2\2\65\64\3\2\2\2\66\67\3\2\2\2\67\65\3\2\2\2\678\3") - buf.write("\2\2\289\3\2\2\29:\7\16\2\2:\7\3\2\2\2;?\5\n\6\2;\3\2\2\2><\3\2\2\2>=\3\2\2\2?B\3\2\2\2") - buf.write("@>\3\2\2\2@A\3\2\2\2A\t\3\2\2\2B@\3\2\2\2CD\7\13\2\2D") - buf.write("\13\3\2\2\2EF\5\20\t\2FG\7\4\2\2GH\5\32\16\2HI\7\16\2") - buf.write("\2I\r\3\2\2\2JK\7\16\2\2K\17\3\2\2\2LN\5\22\n\2ML\3\2") - buf.write("\2\2NO\3\2\2\2OM\3\2\2\2OP\3\2\2\2P\21\3\2\2\2QU\5\24") - buf.write("\13\2RU\5\26\f\2SU\5\30\r\2TQ\3\2\2\2TR\3\2\2\2TS\3\2") - buf.write("\2\2U\23\3\2\2\2VW\7\f\2\2W\25\3\2\2\2XY\7\r\2\2YZ\7\5") - buf.write("\2\2Z]\7\f\2\2[\\\7\17\2\2\\^\7\f\2\2][\3\2\2\2]^\3\2") - buf.write("\2\2^_\3\2\2\2_`\7\6\2\2`\27\3\2\2\2ab\7\20\2\2bc\7\5") - buf.write("\2\2cf\7\f\2\2de\7\17\2\2eg\7\f\2\2fd\3\2\2\2fg\3\2\2") - buf.write("\2gh\3\2\2\2hi\7\6\2\2i\31\3\2\2\2jk\5\34\17\2kl\5\36") - buf.write("\20\2lm\7\f\2\2mn\7\f\2\2no\5$\23\2oq\5 \21\2pr\5&\24") - buf.write("\2qp\3\2\2\2qr\3\2\2\2r\33\3\2\2\2st\7\r\2\2t\35\3\2\2") - buf.write("\2uv\t\2\2\2v\37\3\2\2\2wx\7\r\2\2x!\3\2\2\2yz\7\r\2\2") - buf.write("z#\3\2\2\2{|\7\r\2\2|%\3\2\2\2}\u0081\5\"\22\2~\u0080") - buf.write("\5\"\22\2\177~\3\2\2\2\u0080\u0083\3\2\2\2\u0081\177\3") - buf.write("\2\2\2\u0081\u0082\3\2\2\2\u0082\'\3\2\2\2\u0083\u0081") - buf.write("\3\2\2\2\r.\60\67>@OT]fq\u0081") - return buf.getvalue() - - -class IsaDescriptionParser ( Parser ): - - grammarFileName = "IsaDescription.g4" - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - - sharedContextCache = PredictionContextCache() - - literalNames = [ "", "'ARCH'", "'|'", "'['", "']'", "'i'", - "'u'", "'f'", "", "", "", - "", "", "':'" ] - - symbolicNames = [ "", "", "", "", - "", "", "", "", - "WS", "COMMENT", "INT", "NAME", "NEWLINE", "SEMICOL", - "CINLINE" ] - - RULE_isadescription = 0 - RULE_headerlines = 1 - RULE_archline = 2 - RULE_isalines = 3 - RULE_commentline = 4 - RULE_isaline = 5 - RULE_emptyline = 6 - RULE_bindescr = 7 - RULE_binelem = 8 - RULE_binvalue = 9 - RULE_regbin = 10 - RULE_expbin = 11 - RULE_asmdescr = 12 - RULE_extname = 13 - RULE_arith = 14 - RULE_opname = 15 - RULE_regName = 16 - RULE_semname = 17 - RULE_reglist = 18 - - ruleNames = [ "isadescription", "headerlines", "archline", "isalines", - "commentline", "isaline", "emptyline", "bindescr", "binelem", - "binvalue", "regbin", "expbin", "asmdescr", "extname", - "arith", "opname", "regName", "semname", "reglist" ] - - EOF = Token.EOF - T__0=1 - T__1=2 - T__2=3 - T__3=4 - T__4=5 - T__5=6 - T__6=7 - WS=8 - COMMENT=9 - INT=10 - NAME=11 - NEWLINE=12 - SEMICOL=13 - CINLINE=14 - - def __init__(self, input:TokenStream, output:TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.9.2") - self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) - self._predicates = None - - - - class IsadescriptionContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def headerlines(self): - return self.getTypedRuleContext(IsaDescriptionParser.HeaderlinesContext,0) - - - def isalines(self): - return self.getTypedRuleContext(IsaDescriptionParser.IsalinesContext,0) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_isadescription - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterIsadescription" ): - listener.enterIsadescription(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitIsadescription" ): - listener.exitIsadescription(self) - - - - - def isadescription(self): - - localctx = IsaDescriptionParser.IsadescriptionContext(self, self._ctx, self.state) - self.enterRule(localctx, 0, self.RULE_isadescription) - try: - self.enterOuterAlt(localctx, 1) - self.state = 38 - self.headerlines() - self.state = 39 - self.isalines() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class HeaderlinesContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def commentline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.CommentlineContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.CommentlineContext,i) - - - def archline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.ArchlineContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.ArchlineContext,i) - - - def emptyline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.EmptylineContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.EmptylineContext,i) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_headerlines - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterHeaderlines" ): - listener.enterHeaderlines(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitHeaderlines" ): - listener.exitHeaderlines(self) - - - - - def headerlines(self): - - localctx = IsaDescriptionParser.HeaderlinesContext(self, self._ctx, self.state) - self.enterRule(localctx, 2, self.RULE_headerlines) - try: - self.enterOuterAlt(localctx, 1) - self.state = 44 - self._errHandler.sync(self) - _alt = 1 - while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: - if _alt == 1: - self.state = 44 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [IsaDescriptionParser.COMMENT]: - self.state = 41 - self.commentline() - pass - elif token in [IsaDescriptionParser.T__0]: - self.state = 42 - self.archline() - pass - elif token in [IsaDescriptionParser.NEWLINE]: - self.state = 43 - self.emptyline() - pass - else: - raise NoViableAltException(self) - - - else: - raise NoViableAltException(self) - self.state = 46 - self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,1,self._ctx) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ArchlineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(IsaDescriptionParser.NAME, 0) - - def NEWLINE(self): - return self.getToken(IsaDescriptionParser.NEWLINE, 0) - - def INT(self, i:int=None): - if i is None: - return self.getTokens(IsaDescriptionParser.INT) - else: - return self.getToken(IsaDescriptionParser.INT, i) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_archline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterArchline" ): - listener.enterArchline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitArchline" ): - listener.exitArchline(self) - - - - - def archline(self): - - localctx = IsaDescriptionParser.ArchlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 4, self.RULE_archline) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 48 - self.match(IsaDescriptionParser.T__0) - self.state = 49 - self.match(IsaDescriptionParser.NAME) - self.state = 51 - self._errHandler.sync(self) - _la = self._input.LA(1) - while True: - self.state = 50 - self.match(IsaDescriptionParser.INT) - self.state = 53 - self._errHandler.sync(self) - _la = self._input.LA(1) - if not (_la==IsaDescriptionParser.INT): - break - - self.state = 55 - self.match(IsaDescriptionParser.NEWLINE) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class IsalinesContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def commentline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.CommentlineContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.CommentlineContext,i) - - - def emptyline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.EmptylineContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.EmptylineContext,i) - - - def isaline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.IsalineContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.IsalineContext,i) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_isalines - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterIsalines" ): - listener.enterIsalines(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitIsalines" ): - listener.exitIsalines(self) - - - - - def isalines(self): - - localctx = IsaDescriptionParser.IsalinesContext(self, self._ctx, self.state) - self.enterRule(localctx, 6, self.RULE_isalines) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 62 - self._errHandler.sync(self) - _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << IsaDescriptionParser.COMMENT) | (1 << IsaDescriptionParser.INT) | (1 << IsaDescriptionParser.NAME) | (1 << IsaDescriptionParser.NEWLINE) | (1 << IsaDescriptionParser.CINLINE))) != 0): - self.state = 60 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [IsaDescriptionParser.COMMENT]: - self.state = 57 - self.commentline() - pass - elif token in [IsaDescriptionParser.NEWLINE]: - self.state = 58 - self.emptyline() - pass - elif token in [IsaDescriptionParser.INT, IsaDescriptionParser.NAME, IsaDescriptionParser.CINLINE]: - self.state = 59 - self.isaline() - pass - else: - raise NoViableAltException(self) - - self.state = 64 - self._errHandler.sync(self) - _la = self._input.LA(1) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class CommentlineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def COMMENT(self): - return self.getToken(IsaDescriptionParser.COMMENT, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_commentline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterCommentline" ): - listener.enterCommentline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitCommentline" ): - listener.exitCommentline(self) - - - - - def commentline(self): - - localctx = IsaDescriptionParser.CommentlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 8, self.RULE_commentline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 65 - self.match(IsaDescriptionParser.COMMENT) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class IsalineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def bindescr(self): - return self.getTypedRuleContext(IsaDescriptionParser.BindescrContext,0) - - - def asmdescr(self): - return self.getTypedRuleContext(IsaDescriptionParser.AsmdescrContext,0) - - - def NEWLINE(self): - return self.getToken(IsaDescriptionParser.NEWLINE, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_isaline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterIsaline" ): - listener.enterIsaline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitIsaline" ): - listener.exitIsaline(self) - - - - - def isaline(self): - - localctx = IsaDescriptionParser.IsalineContext(self, self._ctx, self.state) - self.enterRule(localctx, 10, self.RULE_isaline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 67 - self.bindescr() - self.state = 68 - self.match(IsaDescriptionParser.T__1) - self.state = 69 - self.asmdescr() - self.state = 70 - self.match(IsaDescriptionParser.NEWLINE) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class EmptylineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NEWLINE(self): - return self.getToken(IsaDescriptionParser.NEWLINE, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_emptyline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterEmptyline" ): - listener.enterEmptyline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitEmptyline" ): - listener.exitEmptyline(self) - - - - - def emptyline(self): - - localctx = IsaDescriptionParser.EmptylineContext(self, self._ctx, self.state) - self.enterRule(localctx, 12, self.RULE_emptyline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 72 - self.match(IsaDescriptionParser.NEWLINE) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class BindescrContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def binelem(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.BinelemContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.BinelemContext,i) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_bindescr - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterBindescr" ): - listener.enterBindescr(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitBindescr" ): - listener.exitBindescr(self) - - - - - def bindescr(self): - - localctx = IsaDescriptionParser.BindescrContext(self, self._ctx, self.state) - self.enterRule(localctx, 14, self.RULE_bindescr) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 75 - self._errHandler.sync(self) - _la = self._input.LA(1) - while True: - self.state = 74 - self.binelem() - self.state = 77 - self._errHandler.sync(self) - _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << IsaDescriptionParser.INT) | (1 << IsaDescriptionParser.NAME) | (1 << IsaDescriptionParser.CINLINE))) != 0)): - break - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class BinelemContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def binvalue(self): - return self.getTypedRuleContext(IsaDescriptionParser.BinvalueContext,0) - - - def regbin(self): - return self.getTypedRuleContext(IsaDescriptionParser.RegbinContext,0) - - - def expbin(self): - return self.getTypedRuleContext(IsaDescriptionParser.ExpbinContext,0) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_binelem - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterBinelem" ): - listener.enterBinelem(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitBinelem" ): - listener.exitBinelem(self) - - - - - def binelem(self): - - localctx = IsaDescriptionParser.BinelemContext(self, self._ctx, self.state) - self.enterRule(localctx, 16, self.RULE_binelem) - try: - self.state = 82 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [IsaDescriptionParser.INT]: - self.enterOuterAlt(localctx, 1) - self.state = 79 - self.binvalue() - pass - elif token in [IsaDescriptionParser.NAME]: - self.enterOuterAlt(localctx, 2) - self.state = 80 - self.regbin() - pass - elif token in [IsaDescriptionParser.CINLINE]: - self.enterOuterAlt(localctx, 3) - self.state = 81 - self.expbin() - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class BinvalueContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def INT(self): - return self.getToken(IsaDescriptionParser.INT, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_binvalue - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterBinvalue" ): - listener.enterBinvalue(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitBinvalue" ): - listener.exitBinvalue(self) - - - - - def binvalue(self): - - localctx = IsaDescriptionParser.BinvalueContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_binvalue) - try: - self.enterOuterAlt(localctx, 1) - self.state = 84 - self.match(IsaDescriptionParser.INT) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegbinContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(IsaDescriptionParser.NAME, 0) - - def INT(self, i:int=None): - if i is None: - return self.getTokens(IsaDescriptionParser.INT) - else: - return self.getToken(IsaDescriptionParser.INT, i) - - def SEMICOL(self): - return self.getToken(IsaDescriptionParser.SEMICOL, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_regbin - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegbin" ): - listener.enterRegbin(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegbin" ): - listener.exitRegbin(self) - - - - - def regbin(self): - - localctx = IsaDescriptionParser.RegbinContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_regbin) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 86 - self.match(IsaDescriptionParser.NAME) - self.state = 87 - self.match(IsaDescriptionParser.T__2) - self.state = 88 - self.match(IsaDescriptionParser.INT) - self.state = 91 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==IsaDescriptionParser.SEMICOL: - self.state = 89 - self.match(IsaDescriptionParser.SEMICOL) - self.state = 90 - self.match(IsaDescriptionParser.INT) - - - self.state = 93 - self.match(IsaDescriptionParser.T__3) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ExpbinContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def CINLINE(self): - return self.getToken(IsaDescriptionParser.CINLINE, 0) - - def INT(self, i:int=None): - if i is None: - return self.getTokens(IsaDescriptionParser.INT) - else: - return self.getToken(IsaDescriptionParser.INT, i) - - def SEMICOL(self): - return self.getToken(IsaDescriptionParser.SEMICOL, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_expbin - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterExpbin" ): - listener.enterExpbin(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitExpbin" ): - listener.exitExpbin(self) - - - - - def expbin(self): - - localctx = IsaDescriptionParser.ExpbinContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_expbin) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 95 - self.match(IsaDescriptionParser.CINLINE) - self.state = 96 - self.match(IsaDescriptionParser.T__2) - self.state = 97 - self.match(IsaDescriptionParser.INT) - self.state = 100 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==IsaDescriptionParser.SEMICOL: - self.state = 98 - self.match(IsaDescriptionParser.SEMICOL) - self.state = 99 - self.match(IsaDescriptionParser.INT) - - - self.state = 102 - self.match(IsaDescriptionParser.T__3) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class AsmdescrContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def extname(self): - return self.getTypedRuleContext(IsaDescriptionParser.ExtnameContext,0) - - - def arith(self): - return self.getTypedRuleContext(IsaDescriptionParser.ArithContext,0) - - - def INT(self, i:int=None): - if i is None: - return self.getTokens(IsaDescriptionParser.INT) - else: - return self.getToken(IsaDescriptionParser.INT, i) - - def semname(self): - return self.getTypedRuleContext(IsaDescriptionParser.SemnameContext,0) - - - def opname(self): - return self.getTypedRuleContext(IsaDescriptionParser.OpnameContext,0) - - - def reglist(self): - return self.getTypedRuleContext(IsaDescriptionParser.ReglistContext,0) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_asmdescr - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAsmdescr" ): - listener.enterAsmdescr(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAsmdescr" ): - listener.exitAsmdescr(self) - - - - - def asmdescr(self): - - localctx = IsaDescriptionParser.AsmdescrContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_asmdescr) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 104 - self.extname() - self.state = 105 - self.arith() - self.state = 106 - self.match(IsaDescriptionParser.INT) - self.state = 107 - self.match(IsaDescriptionParser.INT) - self.state = 108 - self.semname() - self.state = 109 - self.opname() - self.state = 111 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==IsaDescriptionParser.NAME: - self.state = 110 - self.reglist() - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ExtnameContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(IsaDescriptionParser.NAME, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_extname - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterExtname" ): - listener.enterExtname(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitExtname" ): - listener.exitExtname(self) - - - - - def extname(self): - - localctx = IsaDescriptionParser.ExtnameContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_extname) - try: - self.enterOuterAlt(localctx, 1) - self.state = 113 - self.match(IsaDescriptionParser.NAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ArithContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_arith - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterArith" ): - listener.enterArith(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitArith" ): - listener.exitArith(self) - - - - - def arith(self): - - localctx = IsaDescriptionParser.ArithContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_arith) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 115 - _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << IsaDescriptionParser.T__4) | (1 << IsaDescriptionParser.T__5) | (1 << IsaDescriptionParser.T__6))) != 0)): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class OpnameContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(IsaDescriptionParser.NAME, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_opname - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterOpname" ): - listener.enterOpname(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitOpname" ): - listener.exitOpname(self) - - - - - def opname(self): - - localctx = IsaDescriptionParser.OpnameContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_opname) - try: - self.enterOuterAlt(localctx, 1) - self.state = 117 - self.match(IsaDescriptionParser.NAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegNameContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(IsaDescriptionParser.NAME, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_regName - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegName" ): - listener.enterRegName(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegName" ): - listener.exitRegName(self) - - - - - def regName(self): - - localctx = IsaDescriptionParser.RegNameContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_regName) - try: - self.enterOuterAlt(localctx, 1) - self.state = 119 - self.match(IsaDescriptionParser.NAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class SemnameContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(IsaDescriptionParser.NAME, 0) - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_semname - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSemname" ): - listener.enterSemname(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSemname" ): - listener.exitSemname(self) - - - - - def semname(self): - - localctx = IsaDescriptionParser.SemnameContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_semname) - try: - self.enterOuterAlt(localctx, 1) - self.state = 121 - self.match(IsaDescriptionParser.NAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ReglistContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def regName(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(IsaDescriptionParser.RegNameContext) - else: - return self.getTypedRuleContext(IsaDescriptionParser.RegNameContext,i) - - - def getRuleIndex(self): - return IsaDescriptionParser.RULE_reglist - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterReglist" ): - listener.enterReglist(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitReglist" ): - listener.exitReglist(self) - - - - - def reglist(self): - - localctx = IsaDescriptionParser.ReglistContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_reglist) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 123 - self.regName() - self.state = 127 - self._errHandler.sync(self) - _la = self._input.LA(1) - while _la==IsaDescriptionParser.NAME: - self.state = 124 - self.regName() - self.state = 129 - self._errHandler.sync(self) - _la = self._input.LA(1) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - - - - diff --git a/HybroGen/RegisterDescription.interp b/HybroGen/RegisterDescription.interp deleted file mode 100644 index 63bbb83..0000000 --- a/HybroGen/RegisterDescription.interp +++ /dev/null @@ -1,50 +0,0 @@ -token literal names: -null -'-' -'v' -'i' -'f' -null -null -null -null -null -null -null -null - -token symbolic names: -null -null -null -null -null -WS -COMMENT -INT -FUNCNAME -REGWN -NEWLINE -PREFIX -NAME - -rule names: -registerdescription -headerlines -commentline -emptyline -registerlines -registerline -registerlist -registerprefix -registerfunctionlist -registerfunction -registerfunctionwn -regbankvec -regbank -registerwidth -extension - - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 14, 89, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 6, 3, 38, 10, 3, 13, 3, 14, 3, 39, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 6, 6, 49, 10, 6, 13, 6, 14, 6, 50, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 60, 10, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 5, 9, 67, 10, 9, 3, 10, 3, 10, 5, 10, 71, 10, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 5, 12, 78, 10, 12, 3, 13, 5, 13, 81, 10, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 2, 2, 17, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 2, 3, 3, 2, 5, 6, 2, 83, 2, 32, 3, 2, 2, 2, 4, 37, 3, 2, 2, 2, 6, 41, 3, 2, 2, 2, 8, 43, 3, 2, 2, 2, 10, 48, 3, 2, 2, 2, 12, 52, 3, 2, 2, 2, 14, 61, 3, 2, 2, 2, 16, 63, 3, 2, 2, 2, 18, 70, 3, 2, 2, 2, 20, 72, 3, 2, 2, 2, 22, 74, 3, 2, 2, 2, 24, 80, 3, 2, 2, 2, 26, 82, 3, 2, 2, 2, 28, 84, 3, 2, 2, 2, 30, 86, 3, 2, 2, 2, 32, 33, 5, 4, 3, 2, 33, 34, 5, 10, 6, 2, 34, 3, 3, 2, 2, 2, 35, 38, 5, 6, 4, 2, 36, 38, 5, 8, 5, 2, 37, 35, 3, 2, 2, 2, 37, 36, 3, 2, 2, 2, 38, 39, 3, 2, 2, 2, 39, 37, 3, 2, 2, 2, 39, 40, 3, 2, 2, 2, 40, 5, 3, 2, 2, 2, 41, 42, 7, 8, 2, 2, 42, 7, 3, 2, 2, 2, 43, 44, 7, 12, 2, 2, 44, 9, 3, 2, 2, 2, 45, 49, 5, 6, 4, 2, 46, 49, 5, 12, 7, 2, 47, 49, 5, 8, 5, 2, 48, 45, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 48, 47, 3, 2, 2, 2, 49, 50, 3, 2, 2, 2, 50, 48, 3, 2, 2, 2, 50, 51, 3, 2, 2, 2, 51, 11, 3, 2, 2, 2, 52, 53, 5, 30, 16, 2, 53, 54, 5, 24, 13, 2, 54, 55, 5, 26, 14, 2, 55, 56, 5, 14, 8, 2, 56, 57, 5, 28, 15, 2, 57, 59, 5, 18, 10, 2, 58, 60, 7, 12, 2, 2, 59, 58, 3, 2, 2, 2, 59, 60, 3, 2, 2, 2, 60, 13, 3, 2, 2, 2, 61, 62, 5, 16, 9, 2, 62, 15, 3, 2, 2, 2, 63, 66, 7, 13, 2, 2, 64, 65, 7, 3, 2, 2, 65, 67, 7, 9, 2, 2, 66, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 17, 3, 2, 2, 2, 68, 71, 5, 20, 11, 2, 69, 71, 5, 22, 12, 2, 70, 68, 3, 2, 2, 2, 70, 69, 3, 2, 2, 2, 71, 19, 3, 2, 2, 2, 72, 73, 7, 10, 2, 2, 73, 21, 3, 2, 2, 2, 74, 77, 7, 11, 2, 2, 75, 76, 7, 3, 2, 2, 76, 78, 7, 9, 2, 2, 77, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 23, 3, 2, 2, 2, 79, 81, 7, 4, 2, 2, 80, 79, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 25, 3, 2, 2, 2, 82, 83, 9, 2, 2, 2, 83, 27, 3, 2, 2, 2, 84, 85, 7, 9, 2, 2, 85, 29, 3, 2, 2, 2, 86, 87, 7, 14, 2, 2, 87, 31, 3, 2, 2, 2, 11, 37, 39, 48, 50, 59, 66, 70, 77, 80] \ No newline at end of file diff --git a/HybroGen/RegisterDescription.tokens b/HybroGen/RegisterDescription.tokens deleted file mode 100644 index 7db056c..0000000 --- a/HybroGen/RegisterDescription.tokens +++ /dev/null @@ -1,16 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -WS=5 -COMMENT=6 -INT=7 -FUNCNAME=8 -REGWN=9 -NEWLINE=10 -PREFIX=11 -NAME=12 -'-'=1 -'v'=2 -'i'=3 -'f'=4 diff --git a/HybroGen/RegisterDescriptionLexer.interp b/HybroGen/RegisterDescriptionLexer.interp deleted file mode 100644 index 29a9957..0000000 --- a/HybroGen/RegisterDescriptionLexer.interp +++ /dev/null @@ -1,53 +0,0 @@ -token literal names: -null -'-' -'v' -'i' -'f' -null -null -null -null -null -null -null -null - -token symbolic names: -null -null -null -null -null -WS -COMMENT -INT -FUNCNAME -REGWN -NEWLINE -PREFIX -NAME - -rule names: -T__0 -T__1 -T__2 -T__3 -WS -COMMENT -INT -FUNCNAME -REGWN -NEWLINE -PREFIX -NAME - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 14, 96, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 6, 6, 37, 10, 6, 13, 6, 14, 6, 38, 3, 6, 3, 6, 3, 7, 3, 7, 7, 7, 45, 10, 7, 12, 7, 14, 7, 48, 11, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 6, 8, 55, 10, 8, 13, 8, 14, 8, 56, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 71, 10, 9, 3, 10, 3, 10, 3, 10, 3, 11, 5, 11, 77, 10, 11, 3, 11, 3, 11, 3, 12, 3, 12, 7, 12, 83, 10, 12, 12, 12, 14, 12, 86, 11, 12, 3, 12, 3, 12, 3, 13, 3, 13, 7, 13, 92, 10, 13, 12, 13, 14, 13, 95, 11, 13, 3, 46, 2, 14, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 3, 2, 7, 4, 2, 11, 11, 34, 34, 3, 2, 50, 59, 5, 2, 75, 75, 81, 81, 86, 86, 4, 2, 67, 92, 99, 124, 7, 2, 48, 48, 50, 59, 67, 92, 97, 97, 99, 124, 2, 107, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 3, 27, 3, 2, 2, 2, 5, 29, 3, 2, 2, 2, 7, 31, 3, 2, 2, 2, 9, 33, 3, 2, 2, 2, 11, 36, 3, 2, 2, 2, 13, 42, 3, 2, 2, 2, 15, 54, 3, 2, 2, 2, 17, 70, 3, 2, 2, 2, 19, 72, 3, 2, 2, 2, 21, 76, 3, 2, 2, 2, 23, 80, 3, 2, 2, 2, 25, 89, 3, 2, 2, 2, 27, 28, 7, 47, 2, 2, 28, 4, 3, 2, 2, 2, 29, 30, 7, 120, 2, 2, 30, 6, 3, 2, 2, 2, 31, 32, 7, 107, 2, 2, 32, 8, 3, 2, 2, 2, 33, 34, 7, 104, 2, 2, 34, 10, 3, 2, 2, 2, 35, 37, 9, 2, 2, 2, 36, 35, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 36, 3, 2, 2, 2, 38, 39, 3, 2, 2, 2, 39, 40, 3, 2, 2, 2, 40, 41, 8, 6, 2, 2, 41, 12, 3, 2, 2, 2, 42, 46, 7, 37, 2, 2, 43, 45, 11, 2, 2, 2, 44, 43, 3, 2, 2, 2, 45, 48, 3, 2, 2, 2, 46, 47, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 47, 49, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 49, 50, 5, 21, 11, 2, 50, 51, 3, 2, 2, 2, 51, 52, 8, 7, 2, 2, 52, 14, 3, 2, 2, 2, 53, 55, 9, 3, 2, 2, 54, 53, 3, 2, 2, 2, 55, 56, 3, 2, 2, 2, 56, 54, 3, 2, 2, 2, 56, 57, 3, 2, 2, 2, 57, 16, 3, 2, 2, 2, 58, 71, 7, 92, 2, 2, 59, 60, 7, 84, 2, 2, 60, 71, 7, 67, 2, 2, 61, 62, 7, 72, 2, 2, 62, 71, 7, 82, 2, 2, 63, 64, 7, 85, 2, 2, 64, 71, 7, 82, 2, 2, 65, 66, 7, 73, 2, 2, 66, 71, 7, 82, 2, 2, 67, 68, 7, 86, 2, 2, 68, 71, 7, 82, 2, 2, 69, 71, 7, 90, 2, 2, 70, 58, 3, 2, 2, 2, 70, 59, 3, 2, 2, 2, 70, 61, 3, 2, 2, 2, 70, 63, 3, 2, 2, 2, 70, 65, 3, 2, 2, 2, 70, 67, 3, 2, 2, 2, 70, 69, 3, 2, 2, 2, 71, 18, 3, 2, 2, 2, 72, 73, 9, 4, 2, 2, 73, 74, 5, 15, 8, 2, 74, 20, 3, 2, 2, 2, 75, 77, 7, 15, 2, 2, 76, 75, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 79, 7, 12, 2, 2, 79, 22, 3, 2, 2, 2, 80, 84, 7, 38, 2, 2, 81, 83, 9, 5, 2, 2, 82, 81, 3, 2, 2, 2, 83, 86, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 85, 3, 2, 2, 2, 85, 87, 3, 2, 2, 2, 86, 84, 3, 2, 2, 2, 87, 88, 5, 15, 8, 2, 88, 24, 3, 2, 2, 2, 89, 93, 9, 5, 2, 2, 90, 92, 9, 6, 2, 2, 91, 90, 3, 2, 2, 2, 92, 95, 3, 2, 2, 2, 93, 91, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 26, 3, 2, 2, 2, 95, 93, 3, 2, 2, 2, 10, 2, 38, 46, 56, 70, 76, 84, 93, 3, 8, 2, 2] \ No newline at end of file diff --git a/HybroGen/RegisterDescriptionLexer.py b/HybroGen/RegisterDescriptionLexer.py deleted file mode 100644 index 7915d78..0000000 --- a/HybroGen/RegisterDescriptionLexer.py +++ /dev/null @@ -1,92 +0,0 @@ -# Generated from RegisterDescription.g4 by ANTLR 4.9.2 -from antlr4 import * -from io import StringIO -import sys -if sys.version_info[1] > 5: - from typing import TextIO -else: - from typing.io import TextIO - - -def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\16") - buf.write("`\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") - buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\3\2") - buf.write("\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\6\6%\n\6\r\6\16\6&\3") - buf.write("\6\3\6\3\7\3\7\7\7-\n\7\f\7\16\7\60\13\7\3\7\3\7\3\7\3") - buf.write("\7\3\b\6\b\67\n\b\r\b\16\b8\3\t\3\t\3\t\3\t\3\t\3\t\3") - buf.write("\t\3\t\3\t\3\t\3\t\3\t\5\tG\n\t\3\n\3\n\3\n\3\13\5\13") - buf.write("M\n\13\3\13\3\13\3\f\3\f\7\fS\n\f\f\f\16\fV\13\f\3\f\3") - buf.write("\f\3\r\3\r\7\r\\\n\r\f\r\16\r_\13\r\3.\2\16\3\3\5\4\7") - buf.write("\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\3\2\7") - buf.write("\4\2\13\13\"\"\3\2\62;\5\2KKQQVV\4\2C\\c|\7\2\60\60\62") - buf.write(";C\\aac|\2k\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3") - buf.write("\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2") - buf.write("\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2") - buf.write("\2\3\33\3\2\2\2\5\35\3\2\2\2\7\37\3\2\2\2\t!\3\2\2\2\13") - buf.write("$\3\2\2\2\r*\3\2\2\2\17\66\3\2\2\2\21F\3\2\2\2\23H\3\2") - buf.write("\2\2\25L\3\2\2\2\27P\3\2\2\2\31Y\3\2\2\2\33\34\7/\2\2") - buf.write("\34\4\3\2\2\2\35\36\7x\2\2\36\6\3\2\2\2\37 \7k\2\2 \b") - buf.write("\3\2\2\2!\"\7h\2\2\"\n\3\2\2\2#%\t\2\2\2$#\3\2\2\2%&\3") - buf.write("\2\2\2&$\3\2\2\2&\'\3\2\2\2\'(\3\2\2\2()\b\6\2\2)\f\3") - buf.write("\2\2\2*.\7%\2\2+-\13\2\2\2,+\3\2\2\2-\60\3\2\2\2./\3\2") - buf.write("\2\2.,\3\2\2\2/\61\3\2\2\2\60.\3\2\2\2\61\62\5\25\13\2") - buf.write("\62\63\3\2\2\2\63\64\b\7\2\2\64\16\3\2\2\2\65\67\t\3\2") - buf.write("\2\66\65\3\2\2\2\678\3\2\2\28\66\3\2\2\289\3\2\2\29\20") - buf.write("\3\2\2\2:G\7\\\2\2;<\7T\2\2\7H\2\2>G\7R\2\2") - buf.write("?@\7U\2\2@G\7R\2\2AB\7I\2\2BG\7R\2\2CD\7V\2\2DG\7R\2\2") - buf.write("EG\7Z\2\2F:\3\2\2\2F;\3\2\2\2F=\3\2\2\2F?\3\2\2\2FA\3") - buf.write("\2\2\2FC\3\2\2\2FE\3\2\2\2G\22\3\2\2\2HI\t\4\2\2IJ\5\17") - buf.write("\b\2J\24\3\2\2\2KM\7\17\2\2LK\3\2\2\2LM\3\2\2\2MN\3\2") - buf.write("\2\2NO\7\f\2\2O\26\3\2\2\2PT\7&\2\2QS\t\5\2\2RQ\3\2\2") - buf.write("\2SV\3\2\2\2TR\3\2\2\2TU\3\2\2\2UW\3\2\2\2VT\3\2\2\2W") - buf.write("X\5\17\b\2X\30\3\2\2\2Y]\t\5\2\2Z\\\t\6\2\2[Z\3\2\2\2") - buf.write("\\_\3\2\2\2][\3\2\2\2]^\3\2\2\2^\32\3\2\2\2_]\3\2\2\2") - buf.write("\n\2&.8FLT]\3\b\2\2") - return buf.getvalue() - - -class RegisterDescriptionLexer(Lexer): - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - - T__0 = 1 - T__1 = 2 - T__2 = 3 - T__3 = 4 - WS = 5 - COMMENT = 6 - INT = 7 - FUNCNAME = 8 - REGWN = 9 - NEWLINE = 10 - PREFIX = 11 - NAME = 12 - - channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] - - modeNames = [ "DEFAULT_MODE" ] - - literalNames = [ "", - "'-'", "'v'", "'i'", "'f'" ] - - symbolicNames = [ "", - "WS", "COMMENT", "INT", "FUNCNAME", "REGWN", "NEWLINE", "PREFIX", - "NAME" ] - - ruleNames = [ "T__0", "T__1", "T__2", "T__3", "WS", "COMMENT", "INT", - "FUNCNAME", "REGWN", "NEWLINE", "PREFIX", "NAME" ] - - grammarFileName = "RegisterDescription.g4" - - def __init__(self, input=None, output:TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.9.2") - self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) - self._actions = None - self._predicates = None - - diff --git a/HybroGen/RegisterDescriptionLexer.tokens b/HybroGen/RegisterDescriptionLexer.tokens deleted file mode 100644 index 7db056c..0000000 --- a/HybroGen/RegisterDescriptionLexer.tokens +++ /dev/null @@ -1,16 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -WS=5 -COMMENT=6 -INT=7 -FUNCNAME=8 -REGWN=9 -NEWLINE=10 -PREFIX=11 -NAME=12 -'-'=1 -'v'=2 -'i'=3 -'f'=4 diff --git a/HybroGen/RegisterDescriptionListener.py b/HybroGen/RegisterDescriptionListener.py deleted file mode 100644 index dcd9a40..0000000 --- a/HybroGen/RegisterDescriptionListener.py +++ /dev/null @@ -1,147 +0,0 @@ -# Generated from RegisterDescription.g4 by ANTLR 4.9.2 -from antlr4 import * -if __name__ is not None and "." in __name__: - from .RegisterDescriptionParser import RegisterDescriptionParser -else: - from RegisterDescriptionParser import RegisterDescriptionParser - -# This class defines a complete listener for a parse tree produced by RegisterDescriptionParser. -class RegisterDescriptionListener(ParseTreeListener): - - # Enter a parse tree produced by RegisterDescriptionParser#registerdescription. - def enterRegisterdescription(self, ctx:RegisterDescriptionParser.RegisterdescriptionContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerdescription. - def exitRegisterdescription(self, ctx:RegisterDescriptionParser.RegisterdescriptionContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#headerlines. - def enterHeaderlines(self, ctx:RegisterDescriptionParser.HeaderlinesContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#headerlines. - def exitHeaderlines(self, ctx:RegisterDescriptionParser.HeaderlinesContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#commentline. - def enterCommentline(self, ctx:RegisterDescriptionParser.CommentlineContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#commentline. - def exitCommentline(self, ctx:RegisterDescriptionParser.CommentlineContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#emptyline. - def enterEmptyline(self, ctx:RegisterDescriptionParser.EmptylineContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#emptyline. - def exitEmptyline(self, ctx:RegisterDescriptionParser.EmptylineContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerlines. - def enterRegisterlines(self, ctx:RegisterDescriptionParser.RegisterlinesContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerlines. - def exitRegisterlines(self, ctx:RegisterDescriptionParser.RegisterlinesContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerline. - def enterRegisterline(self, ctx:RegisterDescriptionParser.RegisterlineContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerline. - def exitRegisterline(self, ctx:RegisterDescriptionParser.RegisterlineContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerlist. - def enterRegisterlist(self, ctx:RegisterDescriptionParser.RegisterlistContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerlist. - def exitRegisterlist(self, ctx:RegisterDescriptionParser.RegisterlistContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerprefix. - def enterRegisterprefix(self, ctx:RegisterDescriptionParser.RegisterprefixContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerprefix. - def exitRegisterprefix(self, ctx:RegisterDescriptionParser.RegisterprefixContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerfunctionlist. - def enterRegisterfunctionlist(self, ctx:RegisterDescriptionParser.RegisterfunctionlistContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerfunctionlist. - def exitRegisterfunctionlist(self, ctx:RegisterDescriptionParser.RegisterfunctionlistContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerfunction. - def enterRegisterfunction(self, ctx:RegisterDescriptionParser.RegisterfunctionContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerfunction. - def exitRegisterfunction(self, ctx:RegisterDescriptionParser.RegisterfunctionContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerfunctionwn. - def enterRegisterfunctionwn(self, ctx:RegisterDescriptionParser.RegisterfunctionwnContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerfunctionwn. - def exitRegisterfunctionwn(self, ctx:RegisterDescriptionParser.RegisterfunctionwnContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#regbankvec. - def enterRegbankvec(self, ctx:RegisterDescriptionParser.RegbankvecContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#regbankvec. - def exitRegbankvec(self, ctx:RegisterDescriptionParser.RegbankvecContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#regbank. - def enterRegbank(self, ctx:RegisterDescriptionParser.RegbankContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#regbank. - def exitRegbank(self, ctx:RegisterDescriptionParser.RegbankContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#registerwidth. - def enterRegisterwidth(self, ctx:RegisterDescriptionParser.RegisterwidthContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#registerwidth. - def exitRegisterwidth(self, ctx:RegisterDescriptionParser.RegisterwidthContext): - pass - - - # Enter a parse tree produced by RegisterDescriptionParser#extension. - def enterExtension(self, ctx:RegisterDescriptionParser.ExtensionContext): - pass - - # Exit a parse tree produced by RegisterDescriptionParser#extension. - def exitExtension(self, ctx:RegisterDescriptionParser.ExtensionContext): - pass - - - -del RegisterDescriptionParser \ No newline at end of file diff --git a/HybroGen/RegisterDescriptionParser.py b/HybroGen/RegisterDescriptionParser.py deleted file mode 100644 index cde839d..0000000 --- a/HybroGen/RegisterDescriptionParser.py +++ /dev/null @@ -1,891 +0,0 @@ -# Generated from RegisterDescription.g4 by ANTLR 4.9.2 -# encoding: utf-8 -from antlr4 import * -from io import StringIO -import sys -if sys.version_info[1] > 5: - from typing import TextIO -else: - from typing.io import TextIO - -def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\16") - buf.write("Y\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b") - buf.write("\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t") - buf.write("\16\4\17\t\17\4\20\t\20\3\2\3\2\3\2\3\3\3\3\6\3&\n\3\r") - buf.write("\3\16\3\'\3\4\3\4\3\5\3\5\3\6\3\6\3\6\6\6\61\n\6\r\6\16") - buf.write("\6\62\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7<\n\7\3\b\3\b\3\t") - buf.write("\3\t\3\t\5\tC\n\t\3\n\3\n\5\nG\n\n\3\13\3\13\3\f\3\f\3") - buf.write("\f\5\fN\n\f\3\r\5\rQ\n\r\3\16\3\16\3\17\3\17\3\20\3\20") - buf.write("\3\20\2\2\21\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36\2") - buf.write("\3\3\2\5\6\2S\2 \3\2\2\2\4%\3\2\2\2\6)\3\2\2\2\b+\3\2") - buf.write("\2\2\n\60\3\2\2\2\f\64\3\2\2\2\16=\3\2\2\2\20?\3\2\2\2") - buf.write("\22F\3\2\2\2\24H\3\2\2\2\26J\3\2\2\2\30P\3\2\2\2\32R\3") - buf.write("\2\2\2\34T\3\2\2\2\36V\3\2\2\2 !\5\4\3\2!\"\5\n\6\2\"") - buf.write("\3\3\2\2\2#&\5\6\4\2$&\5\b\5\2%#\3\2\2\2%$\3\2\2\2&\'") - buf.write("\3\2\2\2\'%\3\2\2\2\'(\3\2\2\2(\5\3\2\2\2)*\7\b\2\2*\7") - buf.write("\3\2\2\2+,\7\f\2\2,\t\3\2\2\2-\61\5\6\4\2.\61\5\f\7\2") - buf.write("/\61\5\b\5\2\60-\3\2\2\2\60.\3\2\2\2\60/\3\2\2\2\61\62") - buf.write("\3\2\2\2\62\60\3\2\2\2\62\63\3\2\2\2\63\13\3\2\2\2\64") - buf.write("\65\5\36\20\2\65\66\5\30\r\2\66\67\5\32\16\2\678\5\16") - buf.write("\b\289\5\34\17\29;\5\22\n\2:<\7\f\2\2;:\3\2\2\2;<\3\2") - buf.write("\2\2<\r\3\2\2\2=>\5\20\t\2>\17\3\2\2\2?B\7\r\2\2@A\7\3") - buf.write("\2\2AC\7\t\2\2B@\3\2\2\2BC\3\2\2\2C\21\3\2\2\2DG\5\24") - buf.write("\13\2EG\5\26\f\2FD\3\2\2\2FE\3\2\2\2G\23\3\2\2\2HI\7\n") - buf.write("\2\2I\25\3\2\2\2JM\7\13\2\2KL\7\3\2\2LN\7\t\2\2MK\3\2") - buf.write("\2\2MN\3\2\2\2N\27\3\2\2\2OQ\7\4\2\2PO\3\2\2\2PQ\3\2\2") - buf.write("\2Q\31\3\2\2\2RS\t\2\2\2S\33\3\2\2\2TU\7\t\2\2U\35\3\2") - buf.write("\2\2VW\7\16\2\2W\37\3\2\2\2\13%\'\60\62;BFMP") - return buf.getvalue() - - -class RegisterDescriptionParser ( Parser ): - - grammarFileName = "RegisterDescription.g4" - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - - sharedContextCache = PredictionContextCache() - - literalNames = [ "", "'-'", "'v'", "'i'", "'f'" ] - - symbolicNames = [ "", "", "", "", - "", "WS", "COMMENT", "INT", "FUNCNAME", "REGWN", - "NEWLINE", "PREFIX", "NAME" ] - - RULE_registerdescription = 0 - RULE_headerlines = 1 - RULE_commentline = 2 - RULE_emptyline = 3 - RULE_registerlines = 4 - RULE_registerline = 5 - RULE_registerlist = 6 - RULE_registerprefix = 7 - RULE_registerfunctionlist = 8 - RULE_registerfunction = 9 - RULE_registerfunctionwn = 10 - RULE_regbankvec = 11 - RULE_regbank = 12 - RULE_registerwidth = 13 - RULE_extension = 14 - - ruleNames = [ "registerdescription", "headerlines", "commentline", - "emptyline", "registerlines", "registerline", "registerlist", - "registerprefix", "registerfunctionlist", "registerfunction", - "registerfunctionwn", "regbankvec", "regbank", "registerwidth", - "extension" ] - - EOF = Token.EOF - T__0=1 - T__1=2 - T__2=3 - T__3=4 - WS=5 - COMMENT=6 - INT=7 - FUNCNAME=8 - REGWN=9 - NEWLINE=10 - PREFIX=11 - NAME=12 - - def __init__(self, input:TokenStream, output:TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.9.2") - self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) - self._predicates = None - - - - class RegisterdescriptionContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def headerlines(self): - return self.getTypedRuleContext(RegisterDescriptionParser.HeaderlinesContext,0) - - - def registerlines(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterlinesContext,0) - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerdescription - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterdescription" ): - listener.enterRegisterdescription(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterdescription" ): - listener.exitRegisterdescription(self) - - - - - def registerdescription(self): - - localctx = RegisterDescriptionParser.RegisterdescriptionContext(self, self._ctx, self.state) - self.enterRule(localctx, 0, self.RULE_registerdescription) - try: - self.enterOuterAlt(localctx, 1) - self.state = 30 - self.headerlines() - self.state = 31 - self.registerlines() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class HeaderlinesContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def commentline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(RegisterDescriptionParser.CommentlineContext) - else: - return self.getTypedRuleContext(RegisterDescriptionParser.CommentlineContext,i) - - - def emptyline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(RegisterDescriptionParser.EmptylineContext) - else: - return self.getTypedRuleContext(RegisterDescriptionParser.EmptylineContext,i) - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_headerlines - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterHeaderlines" ): - listener.enterHeaderlines(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitHeaderlines" ): - listener.exitHeaderlines(self) - - - - - def headerlines(self): - - localctx = RegisterDescriptionParser.HeaderlinesContext(self, self._ctx, self.state) - self.enterRule(localctx, 2, self.RULE_headerlines) - try: - self.enterOuterAlt(localctx, 1) - self.state = 35 - self._errHandler.sync(self) - _alt = 1 - while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: - if _alt == 1: - self.state = 35 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [RegisterDescriptionParser.COMMENT]: - self.state = 33 - self.commentline() - pass - elif token in [RegisterDescriptionParser.NEWLINE]: - self.state = 34 - self.emptyline() - pass - else: - raise NoViableAltException(self) - - - else: - raise NoViableAltException(self) - self.state = 37 - self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,1,self._ctx) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class CommentlineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def COMMENT(self): - return self.getToken(RegisterDescriptionParser.COMMENT, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_commentline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterCommentline" ): - listener.enterCommentline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitCommentline" ): - listener.exitCommentline(self) - - - - - def commentline(self): - - localctx = RegisterDescriptionParser.CommentlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 4, self.RULE_commentline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 39 - self.match(RegisterDescriptionParser.COMMENT) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class EmptylineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NEWLINE(self): - return self.getToken(RegisterDescriptionParser.NEWLINE, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_emptyline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterEmptyline" ): - listener.enterEmptyline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitEmptyline" ): - listener.exitEmptyline(self) - - - - - def emptyline(self): - - localctx = RegisterDescriptionParser.EmptylineContext(self, self._ctx, self.state) - self.enterRule(localctx, 6, self.RULE_emptyline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 41 - self.match(RegisterDescriptionParser.NEWLINE) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterlinesContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def commentline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(RegisterDescriptionParser.CommentlineContext) - else: - return self.getTypedRuleContext(RegisterDescriptionParser.CommentlineContext,i) - - - def registerline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(RegisterDescriptionParser.RegisterlineContext) - else: - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterlineContext,i) - - - def emptyline(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(RegisterDescriptionParser.EmptylineContext) - else: - return self.getTypedRuleContext(RegisterDescriptionParser.EmptylineContext,i) - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerlines - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterlines" ): - listener.enterRegisterlines(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterlines" ): - listener.exitRegisterlines(self) - - - - - def registerlines(self): - - localctx = RegisterDescriptionParser.RegisterlinesContext(self, self._ctx, self.state) - self.enterRule(localctx, 8, self.RULE_registerlines) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 46 - self._errHandler.sync(self) - _la = self._input.LA(1) - while True: - self.state = 46 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [RegisterDescriptionParser.COMMENT]: - self.state = 43 - self.commentline() - pass - elif token in [RegisterDescriptionParser.NAME]: - self.state = 44 - self.registerline() - pass - elif token in [RegisterDescriptionParser.NEWLINE]: - self.state = 45 - self.emptyline() - pass - else: - raise NoViableAltException(self) - - self.state = 48 - self._errHandler.sync(self) - _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << RegisterDescriptionParser.COMMENT) | (1 << RegisterDescriptionParser.NEWLINE) | (1 << RegisterDescriptionParser.NAME))) != 0)): - break - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterlineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def extension(self): - return self.getTypedRuleContext(RegisterDescriptionParser.ExtensionContext,0) - - - def regbankvec(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegbankvecContext,0) - - - def regbank(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegbankContext,0) - - - def registerlist(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterlistContext,0) - - - def registerwidth(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterwidthContext,0) - - - def registerfunctionlist(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterfunctionlistContext,0) - - - def NEWLINE(self): - return self.getToken(RegisterDescriptionParser.NEWLINE, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerline - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterline" ): - listener.enterRegisterline(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterline" ): - listener.exitRegisterline(self) - - - - - def registerline(self): - - localctx = RegisterDescriptionParser.RegisterlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 10, self.RULE_registerline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 50 - self.extension() - self.state = 51 - self.regbankvec() - self.state = 52 - self.regbank() - self.state = 53 - self.registerlist() - self.state = 54 - self.registerwidth() - self.state = 55 - self.registerfunctionlist() - self.state = 57 - self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,4,self._ctx) - if la_ == 1: - self.state = 56 - self.match(RegisterDescriptionParser.NEWLINE) - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterlistContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def registerprefix(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterprefixContext,0) - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerlist - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterlist" ): - listener.enterRegisterlist(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterlist" ): - listener.exitRegisterlist(self) - - - - - def registerlist(self): - - localctx = RegisterDescriptionParser.RegisterlistContext(self, self._ctx, self.state) - self.enterRule(localctx, 12, self.RULE_registerlist) - try: - self.enterOuterAlt(localctx, 1) - self.state = 59 - self.registerprefix() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterprefixContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def PREFIX(self): - return self.getToken(RegisterDescriptionParser.PREFIX, 0) - - def INT(self): - return self.getToken(RegisterDescriptionParser.INT, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerprefix - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterprefix" ): - listener.enterRegisterprefix(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterprefix" ): - listener.exitRegisterprefix(self) - - - - - def registerprefix(self): - - localctx = RegisterDescriptionParser.RegisterprefixContext(self, self._ctx, self.state) - self.enterRule(localctx, 14, self.RULE_registerprefix) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 61 - self.match(RegisterDescriptionParser.PREFIX) - self.state = 64 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==RegisterDescriptionParser.T__0: - self.state = 62 - self.match(RegisterDescriptionParser.T__0) - self.state = 63 - self.match(RegisterDescriptionParser.INT) - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterfunctionlistContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def registerfunction(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterfunctionContext,0) - - - def registerfunctionwn(self): - return self.getTypedRuleContext(RegisterDescriptionParser.RegisterfunctionwnContext,0) - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerfunctionlist - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterfunctionlist" ): - listener.enterRegisterfunctionlist(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterfunctionlist" ): - listener.exitRegisterfunctionlist(self) - - - - - def registerfunctionlist(self): - - localctx = RegisterDescriptionParser.RegisterfunctionlistContext(self, self._ctx, self.state) - self.enterRule(localctx, 16, self.RULE_registerfunctionlist) - try: - self.state = 68 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [RegisterDescriptionParser.FUNCNAME]: - self.enterOuterAlt(localctx, 1) - self.state = 66 - self.registerfunction() - pass - elif token in [RegisterDescriptionParser.REGWN]: - self.enterOuterAlt(localctx, 2) - self.state = 67 - self.registerfunctionwn() - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterfunctionContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def FUNCNAME(self): - return self.getToken(RegisterDescriptionParser.FUNCNAME, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerfunction - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterfunction" ): - listener.enterRegisterfunction(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterfunction" ): - listener.exitRegisterfunction(self) - - - - - def registerfunction(self): - - localctx = RegisterDescriptionParser.RegisterfunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_registerfunction) - try: - self.enterOuterAlt(localctx, 1) - self.state = 70 - self.match(RegisterDescriptionParser.FUNCNAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterfunctionwnContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def REGWN(self): - return self.getToken(RegisterDescriptionParser.REGWN, 0) - - def INT(self): - return self.getToken(RegisterDescriptionParser.INT, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerfunctionwn - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterfunctionwn" ): - listener.enterRegisterfunctionwn(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterfunctionwn" ): - listener.exitRegisterfunctionwn(self) - - - - - def registerfunctionwn(self): - - localctx = RegisterDescriptionParser.RegisterfunctionwnContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_registerfunctionwn) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 72 - self.match(RegisterDescriptionParser.REGWN) - self.state = 75 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==RegisterDescriptionParser.T__0: - self.state = 73 - self.match(RegisterDescriptionParser.T__0) - self.state = 74 - self.match(RegisterDescriptionParser.INT) - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegbankvecContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_regbankvec - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegbankvec" ): - listener.enterRegbankvec(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegbankvec" ): - listener.exitRegbankvec(self) - - - - - def regbankvec(self): - - localctx = RegisterDescriptionParser.RegbankvecContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_regbankvec) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 78 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==RegisterDescriptionParser.T__1: - self.state = 77 - self.match(RegisterDescriptionParser.T__1) - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegbankContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_regbank - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegbank" ): - listener.enterRegbank(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegbank" ): - listener.exitRegbank(self) - - - - - def regbank(self): - - localctx = RegisterDescriptionParser.RegbankContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_regbank) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 80 - _la = self._input.LA(1) - if not(_la==RegisterDescriptionParser.T__2 or _la==RegisterDescriptionParser.T__3): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class RegisterwidthContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def INT(self): - return self.getToken(RegisterDescriptionParser.INT, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_registerwidth - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRegisterwidth" ): - listener.enterRegisterwidth(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRegisterwidth" ): - listener.exitRegisterwidth(self) - - - - - def registerwidth(self): - - localctx = RegisterDescriptionParser.RegisterwidthContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_registerwidth) - try: - self.enterOuterAlt(localctx, 1) - self.state = 82 - self.match(RegisterDescriptionParser.INT) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ExtensionContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def NAME(self): - return self.getToken(RegisterDescriptionParser.NAME, 0) - - def getRuleIndex(self): - return RegisterDescriptionParser.RULE_extension - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterExtension" ): - listener.enterExtension(self) - - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitExtension" ): - listener.exitExtension(self) - - - - - def extension(self): - - localctx = RegisterDescriptionParser.ExtensionContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_extension) - try: - self.enterOuterAlt(localctx, 1) - self.state = 84 - self.match(RegisterDescriptionParser.NAME) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - - - - diff --git a/HybroGen/__pycache__/Counter.cpython-312.pyc b/HybroGen/__pycache__/Counter.cpython-312.pyc deleted file mode 100644 index 7414827b330a94b0c4c0372ca47f14815241fbdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1673 zcmcIj&2Jk;6o0cjYdeX9DyX8sfmXS2;UD12g|r8fJw@uNw-6tYdg9HlEz>G32ikY|?VEXT z-pB8~{e5(F7*Kw_^{1oj01womFSMt0D+C|{4bA|E4d7%;OD$CpgllWB0?2C`2-xa9 zsA@u6&Gy3#zFgnJNJVrG=h_BTDc2DVP7yPKVP@j&yUmvC3mHx&3Tv*ciki<_p5uPPY{s3M?=)T4mI15v zqpMtMHaJP>9zlq}fi_sEr4kTR3n!Oc$9L?y6AI>E6#ovjY?7FA+qc!%6ZMZh6`DP& zOkZp^M7>$F>(iGTr{1j0%$%A&8?4CY8Q~6;UdgXt3gVn)Ihe+>!m<8s|Hi<-bO%r@-KDB zPH{Y%*qn$;o2C23sRJNGCp!x}`OzQA?U|ovf0(`V!B2C46f4{L%JqeP9j$wXu})5^ zFty%~ifT%ys-XKVLWB(-PRFwdT?feyf7K?6L{37)r+LhwEx?t3w%ydjh#X|v&o+Oy8~ls+_ew7h4hg5rW>zh?N@-c~ zuw^xxyj53v-m)&Y?0V0F^X1K&Wyu_7m17EyA>4%|O0ok|jUxf2c*?v1yY#gKO*6(1 za)wdt<_&|T50r~a+^`)Nlj#eKi?M$G!aK2k?!tS^rjZ64S6;+UQpHBHt5Qv7kn~Y* zF0FW8GBhYQy#N7MhmgNBMZ*39g#A~5<~!j%ePTCP_;UE_!VWdAo&M}}=Z%eX|6kpu QL!GJ5&+Z=uI+>LA51*q=asU7T diff --git a/HybroGen/__pycache__/GenGeneratorFromDb.cpython-312.pyc b/HybroGen/__pycache__/GenGeneratorFromDb.cpython-312.pyc deleted file mode 100644 index 72ae7eb43f8c1dff6f4d23513147c601ead43478..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18476 zcmd6PYfxKPn&7=x4L9>SQ1unh*siC;Lzyko%FU}F>8MCb|-MiRafFCit~ z+TL9`O*)Y7T0Y)of=)sZmDmjt6aPNr~hoRIJ>F# zRBi3|ovSMeEN419(^GqG&N=ryzVn^$Jigbt`jt+nq2T$K|L3>vxx*Co-|zHF2AF71QPNtuipzXUF#I9ieVBW z_4r@I`%TJ4Ax1+COMizNlCcbga#jYRf|Wz4L_CIaSS5sj0ff-^kcL$c<+2)h)3Uh` z>R9bi9;+MDvw1`LtbWMA<_{IHhM_{XV93Z8LJbpZgs_M;L1<=+AhfVn*8ClM$U1Ma z?+^+)TweI^;v4}V*UtGots_ol2HH80mcifSAsF{fDv%sKMTO)nZG{4enPe8mA!CyU~ibFhLb5wPh{dGR-h)-$wWr6b5Cdvnm&-2hAO_i+J1<=~v-1g3&@jZBXTc{46<#OHUNbU3fNysVIu zd>3+Da{2o?J>#unl5AA>MxyJg=`4P?st1O*(dezlU%?qmGVYk;E7#GKk2>K9__#IMNh0?C?a3X`LfWmV!UNuHLumIcf<;x zgFIDYXW6YotB2w{5Ar(?#&*6Ckv~vb5-M$6W#LtpxT=I#l{`?DB`h|mtxK4!H;0xH zm?mM~88_GR=302sCd{QIDlCe~-%vdUj3{U3s>X@JzsJu(a1&QC#M>WE8%VEnI^%Sq zU{%n)c7`j0CW2y$b9)2uhI>npdHiF3?8;{2N=Wel=Wx1$mMml=B_^ok$KX1Z$ko4j z?Db<`Y7I*V-Z-@(qqG*T3`(}3jtiTh{@-95!%>Rc0kXu0Wx}wSvu$8jMvh8Fh+*YH z*kDkPVHK=$%f`>Lm8D_7O|v;$>SmHN*?UG^)w_yOM(ih$+KLmYEhpideY5`qE%fQu zQYw%-1hQ>*R!xq*dqNXY{@4dj7CK#rwsuEcJ_3OGn`mu-8b zgDI>GQFC;*WfW2(9h^*hmH-kWwC#}~(bQt69G2uWpivV$w>5-UsqOZj#wb?%@9A*P z7!_89a$uY|^XiZ~M9{j}64Z43td;W(Q0mjIrPQ~D!s@oKR2ZiOEF%A8*_ja8J7SIp;Wsr*1r$3mHzI z$K&(Diws_#(EEZ+-8hHmSg;_?|J+{ZhPq~D=QJ4n*fUirWtDs2|xYf-G^r)bAdtuP+P)Crnj(|fj zP5JzO_sHZt;xynp>1t+K7c1ycdP=<#(h50#mq(PI9Gn{o1n(#f2{~A~)ivtJV?h*u zq)=qaIzSu{>~IBIe5@;IgF&RmA&P5tTWa8O?azUw0!+H-MG!4=6V{!Pyo5IY&CVO0 zD>?VIWeM$$XlWy_ZH)9LR7I;zeAxPh7x=rmFXsNXDO!6mx?_k} z4Mp;PXENU$TpqkRygdA)vp*huZ!lhYkgq)WGv~+SAC2F+_R-Z?<;j?-CE9v{H(iKm z5{9x(N}(=|H2=<0yfU;-uU=X|5VO=rx)O!OH;*qLj}=x#S`ndBub*0Zj@OpGaVnuT zy?Oe^>4(~qja+EDp{3NiH*;UlT?*WMb@|npxtdp1zmdBs&ne#-Rh4YyQ!pl7!cetI zG3u&FbE43=qPt&MnaD3$D_=A6`IXDM4Fwc!C@GT}h@egsSqLpk_h6HX8@-W^rE>&_ z8>iyhQeIoS61X+DIu|c{o-cd;_Uv6ntgQWkwganlz23D_y<+9HyS~?jP%8jx+1^b` zuC5Z{JSy68b9{L`UbK%d+P6M-dpcIs6d_GdrJ&C~&{h**H@f25VqROkGWbwixuFIi zU*%CI>pO)j1Gg@&UVOVWW~?C?tF$5o;^s!)+!!-I$E%)uBNqfrDZ7R@*Tg`ORMn=k zqvjL5>IA&%3*TJ0u@F`55XG{TbO@^hbs8d;?T19BHUZWsd=SxtzvZ#tetw^xM%$uU${S}Z-}ZIo|ZDPJ2IS?Ac0aQ$cxBTL6t&@ ziDiN?V91k+awW(Td1=XV(FnXOrCNgGm`uY!6}{xZ{XL$#0^Pv%L(C08V3#MyJmZ+0 zb_w*1Ks)^);o_i^qs|*~!wJyon(GgM#61=)&o=ZeRZc;B{}Bja+iGAx#Jp&(a-4 z4LnSzH3$|67z9z6m1WL-7{u|3ls*gqlMk@NEW&t*{!k$aq(DriNK9@B8WBncM}XIK zd2Jq-$H&dv;1mpS)8x3e!Eq*95|C3?u&zh15fFD%$< zYsMRg9e&U7lylD>yRFG4mK+U-H5y=lz;K-7f`T-Hc{5=5=O7T2qdv~#2oT04En<~x z(&a%lSde>Q!ERZ|+)-$ibqNEyBIm*d;=cd^OktrpURc2wR;)Gig;fz1F6oA)@#Ujy zhUFJy`ih7=p`VHC!@NGcK~e3@OU&08^)vrdj3Dze<6@%vFerriqYS*OM;UQ~aZ;rR zxgwchBTURqkcq=!PzftQw^D{^mY7mnsU_y}9PEIcP!3CsDx3+XEOVJ8p+UJKQ~L<3 zyb37~WpY-Dr4Z*}OpXZ^9uq`LXF>|hxeB|5dk~V3QACF;3MpAN^oDzA+XGsfCd5FP z`>ujW^-2jcOJ98fpmc;onhf_X@t zx!9pj{<~`FG@vQ(iDzJAAlMZAi7?1XV-QjRhNu&Pb{Arhx^R;H51?=1L~eS_QYs{u zS|(|$WQ}41fukJ)D4K7zqm-<;K6P7ZzKz;> zAsMW9^Se38wSpKBj2Dl9hMLBhS*-e2y=ULQ$sH5GvzRn?qIe`d~5 zYIgvY)l1Cc0${EL#$yo~k3b13m)GfIfg1}sKJVl_aA-k}A~|;+u;2zUz!UrltrnQ! zjwf_YP*zh@6O`MIAGZbNc3YJ#sIc3P9kV^5?Lh`gWRUfQ4ngiw+a(PaVok<=G^n(b zEW4UROA6sJ+zCt}ciUQ^BN^ov0f4^^ z*b4A5Lt#V-0!KuV(B`2~Qm}Mnx#TfbON4HaN35@h5|-k)We;!Jv);Tu`hHi;^8B*m zkp)butLi01!n$MSh1DHvj&;R*qUE%w# zL|<`4N8J1?6VXXe)a&Ob0}uPAAIt`UV}cZjjI)F3Mz$KFyYcNbb3uH&!2B-?j5QZA zvtkHeOfNH!#9n?neTV(I_Y?0uN3?J7i;3va%h5{?erV+3apwcqc+`C@8kpzZ^UyL( zwF6L3b3Dk!CT|fu0A9uzIcPEUdmBL$=Rm)mc%xdS2b{HgN zS(keuQBt6pU2j(9vyb7qDV7d^Q9_AcI7nsY4Xpb13V6Gs(A$l0g zs$anutAlwY_VVe$ySx8O-7o5*XZxcAFY{+FMXwA;UvcqQMjxIWd*GgodS;;20^Nd* z+nG}cc!4I77pM%dCg>glxEBdwJq>itI&9-|mo#i+30T(8@w*y%b;aFl z_qu-ZYV_g|-#+y4w&6&vgu=ysRPS|IwOVl~cAO z5~NGsU3+aQ85%mO03FUfssRCdi!ndt!`lzSTvE--Y6ufOd0|>YA`x8ousX)hEBBHB4)JmRHLN9Qj^i!lq zrg- ztJ?+zqeAbZ)M92luhP!lM~+n>;TxgMx%mkSD# z2`(_)cW5j0Z~-jI%}@&E6Mi2s7|^>Zh%4_tB_5=|(;9W>nD3;U_PtG8>Q>vS*Y z#L_7&HIdSu=9aUkGb-3M8SH!pD}02o59K~?EL9!-vem=S3vE%PCX*Le7lNTShPZ~Tv*ku8^ALeE8G)N0lNq8 zZ!C(alZ=0pqSgDs5TPwta;)SmPpmbpoqO*PU$kf4!57u@+WH&q8#1W!JA>)wj^!OI z%`5KJ?wG-j?QGc2lr(*vd8jSJnzlyqipR`+se0 zSSw#Tzta5u3sGZ3qzwWvjw~7Dh8o^b6F1cJhWb17ojsrAMf>{WeHZw?3(<>LVtvEW zad&jW&yNRyL7iaQnW&-uF+~-0Ag9uGFp*}k;Njs6j!Ru0!rQ|e_QVa1yrJ<<`JGdr z0P8y!KRd*q9g4op#?HE;USD)-p7)|y(GK!N)X<3VdI-E8fCsjji0TiUYRc3|9NC{0 zYFi8C&P**kWp*2YnIH!!_(LZkz5Ris3cR&w#e#Cw?zcT@D;3$?^r8j*NFeJn!RNAW zGRNek&FgZ3ZQAAs`FC>bma_%xfP?fuT>uNz0j3$US7AMgHW@ITSdq0r4yxL=er0 z5$77~&UM2&D|htkTTM9GL5|_lZb(o#5sh{L7jS4gU6tI)K*io&=;-~v2JRzRfAD5 zTn(C8m5mgTVH|6+EzC}WU?t^}Q9IIJ%Rs?va!bp716`1C{ zHt6UmsSyr4GxuOh4Eo=&w~56~hHON9ve~(^nN0tI7TCwO=bP^th$dW#DN8X}z5z;D zuEy(CG7vz(OiOYUX}behfaH>0>>!F_vXF8jWs687@j)^vda=VYxcUbFq?R;A`T#)= z>uAbpa|8PfJZ`;|f zmO9*{u-!Q@+fl(?_4T%1pJ?ZHJ8eE}3pcTFr;|Ng>DLHK5rjYw2USw*piOM(pK>|f zquE+Mq3fT}8oP>XgnqaK7~pZr9mL>y48XEVabQTIxWf?Gb3_3JWh8C~1cC}N#gkBw zpY{3R-WU2r(NoEFLa`s0Chi+}M8ksF!LnrV$pIh@&_x=oh2txEf=PD*>z+~fFA%bd zh$bj)fVJH4=Io8xH($H)+B@8>+11&2Sv_A?|1;Ugs*hB63?Jpj%8teKP0{0nynZku z-(ZyLmuR?D6)gtG9bbH$Hy@95f()`Ww^kT4RBlkTu6o^&$hWMVxpjW^{M#2+UgGns zmQ-KMpkPC#R9~QfW8V4G7e4Kb7Ps-{wr|sz%C|)HUz-sScJuceavG7*8o`EfH;1=& zMlD^uw(IrICts^bZ=}KBZzyQ&RcrjLtY?A$=Nd@W8l$Mq%>a$W)i&gg70Trg36fMe}&zT%3{al^fQY8D_s%WXm`MgvH zrJq-juu9)@NVY|nL%jnJwZ}h#`ONeHrgb(DJyQA=)J#6vH7)7D0j-BgYCZWVz+@O5 z;f89aHU@f7fgE*%l*3Je0Y?j+(M~4i6N9%3wl;wSMpW2IoD7ZG-bt1jqr>u$9B@XN zdE1lijwX1gQjn8dTx_33Ba_P021^MG2{#bfb`gOMG01X*Gb;wnhba@i)WhO#5ai^n zLV5@7N;yLe{(gqd@q!i!2Q>C!+BQUZCBhn_- zfWrf)Y}> z84hqgImY!N&D-?5DQ%TT2U#wgKY_O$w>=rNn;K!pdWL-h{!arK#({~7T72f}1&p&^ zF(ae63~jX`En9%(oG9PcF}zC5HAH_?Y0~9m4^&7HLMcp>`=Rm~b5@vj1!`F%V)UU& zno%hRc6uqK$(UU&Ta>wblbCoznxr#>UJL+bb?}!5GpL8Z{6J+2%WbV&smoWB7v2ov zf=~f#CVROqq|3VAEFlBZJdIl@FKa#PQ}y($=rGeS9)@0aB(Z++8U5^hs(to;il3^N zpX?`p(L*dpRno}QaaQ^(VNH}EU8S`FacT0s3}e=oZKa0tBw9dyGJ|Y+)_SRnejo1o zKqcZ5F3i3{LWL4c5Q1`&mhY^5}H1BD#H#odPiVKptQ5? z$x4Zg(>QDl8KGsCbC{f9#*BTMgIqgl%qvl(2m zcRAtP3ymn6fwGiwpF%7|;nKmmY$Fao*a653TtxG@0w71$bk(=l*VWb8_u6LRO8}yT z%@Ba75mwpU9*>K4qv?*QgsEQo+j@v$dAR-b*`DSBxZW5DxIlSw`)z@7(iH%gaH~r- z6E89vvze&hr@4OtRDjz>bZ^isnxawa?aZ`eL!~`XNnrZ+!=HFFCwN9p6vV#$DZSGM zN?&IqsGeQ@18rwTg%FC9>Ma!RYp~ljYIQ~)8p7d@A!x@n_M_yoN(yenH^Xhn0ymwv z748@y|3nY!KuSIabNmz9#=S}kGVKkZX%hoxFo$TVfK(Xjz;{86$17-v>Cgov_lt^! z2C66V2=2hNq=IiHg?QUjixnglKWKisI;iXC+Bg(Ng&bTKlW46JmjxujF$x-XklAaq zs|31FU>uyl_`L!%J1Hm-{!Evy81ZX?u*lh-=3DlNgX2q4@Di7u=xiL#r;KgdjsawYW4p+nQU4d-^+w zomNm`R!gz){bB>gXQ!r`EElx z9k#@x9%qH+c-rd%T1xk@`jcl$a4#&=)JjcXIn7@C3+T?@1FFMy>MJd|)_B|avE?I6 zyx|nzaOz%1tYP5SCFjs@?ehD(4m>hjZ*)Gg)J4tpkxo#pR*Z3LEpM%jTN`+5!yR+f+7PogM=d9L?a5?? zTP3R{D|%jA9qIhiv}5J)+L_g3F;fj#5_LzGXjBCUZe3Zu5-(}wOB!!Gq9u*7l0(tr z!+ieXWv~iEtw*TBHAXE5c&PL>qRQXE-aZ>|tYPel} z=eeIZebN*&b@8gMi0UgPrPW8~zk7V8`F?Im#z+8pyyhA$hTEWXU*_gzt)nx&IecR{ zS~B-QH=i&S;e}eX!{--(7v5C*nA)MPiL@n5J0k6m;Bx9qufKGA_s9GG)4tElUsOiT zeGjx}5^&|UJz+H8>|E~rtG2rb|FY-Tr7zvS7A@O<+Yl>jykGiK%ytjFhyzlwI7b|S~(!68k;P-=TXWn`ZK4!Y5U)8T$ zQHRg;h6RC9oJpQU%C@z^b2e$5ntzzxkd#d+jiSk`*&OftAEqd=X@OzIvur;Nc zwBNnP@9TVE>q<4*FhGAB1yo6Sym&ufygy$20$=>Xoq>DudxKx-qL;wSJHcPN8s*T_ zJx4dAq2EuRM5lHaLwwu4%tg%XVumo&$++Md*0;Eb@GW1`Iq&GaU>`7R5tvOcp zKh$j6Ve&R~up~APQCeNL-2)5fM)RY5V?4it&##E**Yf$bx2vQ1wXysoNu&DBlI0S( z0Uc@HzE>J>uNamFZeCfw5;xWIrrLE!)KnWY?dS9N!wpo}C=HLax~QQVw;Fgs3gdbk zueZhZ)x5rXec&gT-@kk}C)#&D%DSU7!T8K;{LE`G!jo|05ymwOmj>W%hVI#xqQ z{v~`@Ut<2S8K$Yy^YkA!k5gr*XmY7#-E>-|{hNI4Y28-ObS@k@#F}xJc&0&Xra@~4 zpC@R|3~0?V@I}*5hdlpi3x_O-C6 znNLaj@|2_xDSKX~6YtrQzHOX*U!;*(IkyUkaX-Z1Z46*5P@>oT9ZbE80g9L0zr*0) zVsI0K{{R78j7|w)qOgI|7knhMRoLSG92@*c42XzSh^Z+Iu3_+>F>qpV8-tG^5OhQ) z>LrpGh~U}`A?RbQbO(d9IP?j=Zk2YpPciT35cu(~g*04@MZu-)nSzUWD?8ZuZNwL` zjUJ8*{|E%vDR30;DBsTde`mD3Q}`|9ny0xqejw9L{}ZtB8*TW(OgFue_y5W9U(V~x zgpdhtHqPOAa%0;)YMj_{j5aWwo{YcW&R_W z`hRkl`LmqwaC{}5@7ca~NLj2!_Zm4H=*68$7rZQZD6OZ1d@c#oDJ>YZ=}F(LZPGR4 zn%v^~@r%242}TM|^@@Q*_U}raIeKRjoVYY|6$&F zbAEXqed{M^{8))N*AMcBgSTg6h8KD5i=uP=1pO#o^Tkv}yn1ol95Wogvzs>@=e5Vh z+ApSE@mo9&Xn&Hy-{ZZ2#6cK->t^~;WbPKf zdclaiIZ=S_20s#1VVQBvWSMK2i4kP_nOV&AGYgoB5oCs#*Dz|9wWH+R&2*p~o!^O} zx>H83hQQCO5LN@fR{}o~fw#kkhXu{>u*b(vPhwg-JbZ21F)5aC_`$fy=gwg20tVzZ zH+~2t-V6IznEDO|uVc`H!CzqT83u$O{sdFEG583BpJ71E4R8 zpfb==xpjk~N(Pyzyl7KyP#89=6i`?|nZ5M&?nF`d^`1o0^!46EQ4hYpe7zH@oBNsT zT^o$Tths)AQ)_^Js#oc{$t*lZ#(Y{$CvYRPX=* diff --git a/HybroGen/__pycache__/Insn.cpython-312.pyc b/HybroGen/__pycache__/Insn.cpython-312.pyc deleted file mode 100644 index 9e6decaf027fa7d14b4fbb7d65dbd498be56a58b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8549 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 diff --git a/HybroGen/__pycache__/IsaDescriptionLexer.cpython-312.pyc b/HybroGen/__pycache__/IsaDescriptionLexer.cpython-312.pyc deleted file mode 100644 index 9094416abace4d880d162dc68b16468b90e4eb72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4975 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 diff --git a/HybroGen/__pycache__/IsaDescriptionListener.cpython-312.pyc b/HybroGen/__pycache__/IsaDescriptionListener.cpython-312.pyc deleted file mode 100644 index b3af0997275765a67b91abf9fa9a8bbb075451a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7640 zcmb`M%WoT16vk)#iW5KbXwqlwI4`FTB?)O-lG3Ejt1qG?DiuN@$a3Q;apgxkcB;f; zL8Y=`!G=XaV$ltY2*HAX0~Q?#$<-{n0T$gArK_$u=iIsO1ZHkrxL%BA=J%cX?wNb< znVIWfB9Rsae(O!oawEqT<##;bKfkrJzXUsvl&q3f^U9ANRngQ3p{!R^?<;y!)|d6? zJq6DioG%7IQ$O-3SCwqwp^|OVygzu^wbpzedv-mk;B!1osir!-{7M~puCk-f>*dUX zR^HHaTa{d?xSG++n!dpz+16tn?EmV+CTYr=npM_3Syl7i4cdil|Bff?dFWg73%D0} zfOym~-UmD=;C|rE#5*111HeN9-UK{M{G?-i5O`F;n}N3yPdLW60B;xY5bzG-Nyqpw z@J<1b0PiAx#xXt${Fs2Z0zXcC+%dil_(=h82Y!n9q+@&s@R)!f0Ujql;~3uwJR#s+ zzKK0#cuK%e0Usv*p<{eE@G}A)1O7Jg zb;tNP@KFKp0X|0jwqtw(__%=g0zXT9(=ome_&EXZ2Y#M-(J_7i_@saj0-qvYag0v_ ze^0=NfM47_ol2QU4_3dWT)CnZHQn@XRCYFa;o}}yPxqk)LJ{0m_SEG)WzS>!%3A)8 z-VA5Us81wbT^iji6|{V5BaFJ0A&uXmiCN49p&BU-Vd>AvDD2Mem>uV>|Id^11Rf7~Y2+MVyNs0*Q`cdIUCBB6=(An;qItuJVtzq}d#Qe6FaKt3z&Wzxi@JB#NdaIftxzN5*~7v$mIG z{&*O%X{IIlMk(XP!d7LMtOwn!G3UB$PLg{BGpb+Jy}H;{SEPAkN^`j)J?`AS?W*@B zdD9%PTf2@kNSljRq&ZvpXnC#RUR`XWTauhJv%cyq}r%A^l9Ej3nm}&Fh=mr?+#(s_WgxZf2T0l6+fmMq9SMZndN?xhu()WxKeu zb!fIsQNCX37=7{abHOCZJ{|ltLG}4RoBslH-#i$N^)(+8O%%*f(cBDuOxZ0 z`Ma`3UF&*>F;%AdT9Pl#U(43@4#VwWl1GwU*;^(Q$>l>wvL*UXk~58DZtQxWS$W3B zJ(lFlGX6j-96om~(f5*^DPwLd%GlEEN%F1taURxo#MKJ=14Tbca^`(Z#-fZZ-=7co zE~lo=U^2#r#-Ol5FIGw(?oyjwz2O!Gqg8E=vESfLD4Be^dwEBWeAQabY19hj1XsHC(@5It z-x-_@Bg3U^vlU+aC=rfE5aCy?83lx|teoJ|wT|DL6h!ZA9GypmOVefq?k&8EaBu;^ zMFQ+ifCF5I)-NMy<&R5_=o1Uqna!y6SmA^|fUY44QxWFpaZy=c!t)VUuQ*snu!_ydfA9ywzVtvPAzuHh+VR^t1(q$j*Yb*8!=19;K{tyQ*Y>r_t-b{k0-xfdFH$Dr*GT` z(BnGgY3~}qq@qgz4;FMk0EsS99!yW%>%#9!>I^kb4GEPAf#iqPy)LBIMM^=(Ou@uV zp^uru5Hm$W%oN6$DNHd_m}91}#7vPGGlex~ilmq+l4GVwiJ8I{Gev656lpP2*kh(} z#7vPMGet(s6qzwoWW`L89WzBv%oMpXQ{=@=u_$JW{Fo^g$4pTWGeu#{6iZ^JSQ;}$ zQOp#@F;gsynW7|Sisdm=I29?x%|*84ifi%!4O;{Jy-xFyI;xvmN>x*C-AUMR_ES3e zJ58Np_ERTy&eF~kxsZ(cuV4J?fB)tm{kIo>_)p*c-Y>uWpMLTE@BZT-{F{IH_G^so zL=ME?{IZ@l(|X3t==Em3-e5N96U+&EquJ=q(VNUBz1eKmTg(=HqB&7-HCy#b<|KWx zH^ZE)Pcf(HZDyN3)tstNGpFh8W;^6@m>mpF{up!#Or?cMVv?CEZ#JXHzXbg%iyq3* zuO`n1#=v-U4Mszw#b7lg8#W~xAX5Tk6#u+=j0yhC3Fc0VImw)C?qV$XXRz$HSQu|k zB9q8i#Xp1fDGUFQ#3VtD0GT91(qRknKr@6tZwC4d$($vbNr68b{H4O*iFD|bG$xI) z!=Hn37#%k!EDoz9*+F7%eklnclb2txq-Yt_fLFm|nFk>IWEN@;v{^krJ%yT2m zKY_5|BtY+CddX>gD*6J#WoHmBcN+8z?JPBz43MA{+C$T2l?F=!U0!KO(9u zD+ye~K#OR4O+7x z4eQ^Qg8q(9Lz;!&-T^q}({yJShINrX@7jU>9jOR+?lw5Q`HA$d-G&S+-M!n8l|=XK z#F(C41a|ZJciZu4&t4<+!rpZB@7s?(v%lA9!18+!V9XOw8dGTc$*0hN;0a81;3+=; zQ+@c<_p~vArk~D4fB!+FjiwI{Kz``JfkT*wbzy$jVe}tjG1Z~N00FNp8^N3YrePJkRtGpKt+5%N#s$$ckBp7DhQ|i_hbxbd)U2th ztE;Kpa{3@Qw%Iir^0d4ATU_n|Zt$3AaBOr(Kj(IF6~|5oli+u-e|XUAVw-w8xg;nv z5&pZ^!x}q5{nVWL)tp(X)R2F{J#9)nZ+_A2OWPJObx03e1Ey`#gCZvKLwmrqRm!6% zK=BYcnIc9}kD`Fc4~jgB(jMeNQIDc%Ma+W~t;jQvrA01U5u2czUSI8^Q-_}FcQVf58)=56`R`}u}#B}N7RMVL!SaQ_x?Sih&gM7gM59ZU7n ztge@#DVJW{^M`OWsvN{8i18xr&})QHlgl`irb-NtVwx7}Jat}oo<7eE7!Fed^Z}T5 zPr^7qqdP-;aN{FxoF3PS6vjpRoLx^17|t+fXh=o%CPFP%vF_fa!@%(Vp{_R>ei`^p zVfDQ>*3g^ECiJGU#$G#X>UFT@-gMT|o53dbX0q1aEHV%tK$y~R+^GN`8n>RAr;IH8_WsHY6- zDTjJiKs^;uPbJh-1@%-zJvC5It*dTmC{&KSc_FEH4Pm@< zU!d4LSG~k|H?WI0&%-ZTr0%2$>R2~n;~v5iQ58k?XtLi>{f`|PvW*g zT!$>Km)#C=Pms7yi0hKYJ<0BXxC10^C&cZN#XZG#LtNik{V84V)7>zCbh4Rol5+M0 z9a_7LH&q#0ak$Qz{IPjmd*_~}j`o%f-h`5-UCmocyiCbBf+r9hKro2l1cE~)oDD{* z7J%4>5@(85lvY@f-rF5CHg|2`-rCs{WZD7fJDaw*292Gqdpp`Y!PDKky}h}s15&kj zVhD%q28Vpf4EknJCNzUPGlx>783K&xLpj%s838VDGq`fi;3_zSyXs6bf)oUZ$_#G# zGq_ke?ZMA}HKQew~uKG(2oBxnK;p&xkfaW)JAZCMK-o40- zQ(uEF9oLQ1;$ln0X&UUGT;S%xjwWs#g>M>?MFQ~*TB&|F3t^9RWOaGtALQ| z9vnF_-0vCVf=s_>G?>h~1_m*SyJxJWttpu1KGM&**ygcO5A=9*Ka>(QLYW>HcPyCL zcMReN2l_oOw^JX~yIsSFxV6wsZXJN2xvy_vxZmyW>vLoC3knJ*IK+)>1mInyoNNN2 zC${$lByr`(oOi3>q{idwT=~og0rjlusb;^|OH)UTg37D4rG}C#t=neg!ntouq zUNqIP-QTeNj%TXtkiYBDWai--_jWds zrCoZKaT#ErpCU=qxQv7;a??)E@84+!G`QK8U}qxgOu0M)3~3!|1E zXJn&R2O|bo2I5Xr*L0oN7;XbRkypZXfbW`t+l&F|=e8s0M6d;b8~Y31qT)5y#*bTt z_;M$pockzN$CqnOeQ~qjns<56l>-55?Q~AT*_N+u>!a z=sXf~L-LN|BSH8tc11UJjqW6?rIQKTfnDi2eayw~Ix*}LUIT~AUodS;Xmt}JuIWhk z@GK2Knw^l;yJ`;IAX_tEfV}QS04Atud*+nA%x^CXly96W@Aj8>`+9ay+V}XZd*;12 zxZThM;Ntec5082Z;6qk$u|sf*$gwViXYX8I{-99cS;%-_3*{aD@*TdNyC&`3K5KV4 z%J{m;XkP*z`3gNGy>y5WTsOt-0I!qgv9a&k-O<_yEs#w(PK8m>3gZBWKs)S5r@X7@ z@IvJo&q1|r+(BVz+e@bGYyI}MKI>Y7Ptb%Lk!#e&4anP!LzQ5*5j=7g&$uo$WVy6) zotBbkTw)qfq)2vwpdA(t7Y7K)&~?&5Z!5prbJtcg%TTrk{uR$_N2Iw< z4SLl5z#W9fafcA#ZlFNkgc%6#a~axVrmtgh1pp+}R|Qhm5Y)^3wz8`&cWu>(dOblM zmY|vc2hN#{+ceTDuuWU~`bNfB=zQF=`}&Tb=pPnhU^jISk9lA>4W{y&rEI+lGO#7{ zi#RSv9L`SeDF8y+9?s?J5XK(IV&q|rOcHkJ0oU+wUmvV(WSPgAwvitU>B`O%7lUn( z;tc$EWBT8|KutUH&YFJ(^65ff>DpNee|L2M8h`JZbmqM}ggpeVn@yn2wZ7t2_aU}+ z)6N3PVLP?=e*62(5+lN#$U>KpIcwL`Lxp?2AK4 z4yzo_KZwzw(!`uP%8XkPlFcdyd1dq>3shvE)LzJe`-{rGE@ZN*iJa@$ z80Tr_I3S;a^B5R=24Zn$0a=Aq6fF2C?!-3GoXd>^0LUkvY*-Et-ldu=?4V-hegzV` z{QxGYU*e9k-fv%joqfCIcKeO?JDv}`?|CQfy=P587N1XkG5Nx&E2&pnri#}2i`E59 z>u2dibKbPoHf7ECTk|iUx|$lWmQ82po^3g|l?3Mj?G>=*hl0*;e{uV{u30OUl*)Uj zQ!>w{{Pv?H%2srbV$7A(g-g$F!7NxRW}mVy_gj}=bzJ2F)*4x8k>6T$rRQqRl(oWd zt@zhjBV_*9S&LBc*SbD-mjPBcEKSs=JnCkixw(S5S=`v{WZo$a-Sy8Gz)HlZf|cASjG@PtqjblUW0h^E8m}1|Z_aCnG$Wq$d+RnSq?AdM&KQl?bU5 zk(?L&R`4eg(mokT`;?DMG+$si-Ke6cA1)nFXdP}R^aHmGfF_+@6=y>wBK`YVTsMMt z072cLHqG(^L;^Xkn^+98S>r!uSjnN@-6)~V`! z{_1^`nfraV{XfI-N`Gc$psHo6YOlX)uW#S}$;@7#tv3pF^jLMdQ_mqqFK`V_f&@t3 zz1&wIUeT|m5a5k_K#EeOA7L>OJ9W3ediP}J9-nQGvQvBfRXx7ldnPmY`fPhYEuDHz z-l?`$QCJqeS1YhrtK*&Kk_7GsWQ#mj_xP)YzEgJVZhzHo-=4jbnfrXUeSEjdCqMde zx4XXtfP!d~)B6yIPQ|R*2(u<*lGU6VA#5WsCmQoo&Yj(X>h8<9vo(JE8lQCyL4ZS6 zNPCgn2r&%bQdSW*#Ob$z zxa_X264{W|QKrL2$o?=ePC?#C1L2pU{BVSkbc%mr5ZSH|AeR!~+Ca)mg70#_4G5FF zwhF{|75|!#VAVuAkire2|0sfC1S1GW5sV=~IVITyI9#zfoM2?^amUcdBES}N#}RM< zh=7D=ow&Ui_$2^;j1kCgMrD+K1qM7%=&msLDg6CavfjK;cexv%_K~Oky2}Ijv|o2G zS!b?CHmXWsqpFaNsub9$N*+n9U7L-%u2;=SoTn=HsbQmVDy!U(2D2m=lCU%~KdkQP zYKpp`<9f&G5NkB#P!$G`Lb^7{LmvgAoqI2gnR|d%L|~jW7%pHVg_ZRTGtPt*6GJ)S zZ9SxWhT^iq*vF{s)abCH)clC08dOYaVR*_A(>dCtC>6H>l@r>UpenUkl?)zbrDk|a z#Q4xV{i04glr^f#ez5lh?_BMM%G4o5aihUPvoySEm~m<+3J^kLkxP$fBy#ix-MKa> zbEUdOc|VQwEI-n(#1WQXKduLsKT`~YGPL@mT8t0_^vHYe^E(?n1S$;%s26^`xT%Kp}oy=4KaOUz70I~v~gaGao0FeCReN*eMU;=2mP-jSYG;wK|39Ah1d;0pS z_$?tF1F_DaqjPM}VE@5k7YGz2$pP1jQ7QdwKL`?@aqS@5G7sm)Twg$N2Enrka3gUF zx|a#?gXp4v7?hTtv7@e0?s*82*g8RgfS7v=H0eDV@$}c2^FFK~g7l!lZ*RC>_qOA9 z_Koa2Egx)sZ|kIeZPl7ORfIZ7*+o zwe#i9tJRZvD=xH7XXXV8S56hK_ZP1B6>RWlZkR4Exvc-DWjZTwDr>nvYk4566#UcK z`GKXYrL&Bo__Ee~WTJ8_uX-kP>U@s6=|zh#=wGr-+Z7R6<=WkwlZMtE{$It zpUSNDXV$*a@~7K=uzkR+H%Qt}(;{vxh7kL==it zO&Ak}fnH}^h@jbt8IZV-BnQz{URr-~J(-*h{=$aqO_TNwKI;aaoq%+bn;-PJH=qK3 zi6`r?N|DE5ptn3e%y?58t2T1D@?1YYX>ambn|QJsMMT;x;tLS-ILX1xC(xmL+AKtGF^?W9Xs=WTQfdje zyv%P~cExkoR*u|q9Y3Ar@)|v4BCl#Acpipyz=|xq8q>F-@Ni6tXdu3ISCk9nsS&LR zq|^{Z`Q7`jtqc*Z5RtC;=SOXd_Bv z+`3WSxl^oJ)yC-f7D&ZPo)Es!=NjC7NCqMB){;bn@YW!i0p3~~TTq5pFG;cssajBb zDGc{&!w`QJY2yYF)D&9IOJ`!(j>Ev**$&84r;BlrJK`nwB1i16hfar{J zX7D5!S72)3mnov;*F-me1?SmM=w`|9iZ>+D;DZw}sZe30{A z&ZNC3j3r*>FIp8atwt7Cf6g>ZXGi0V&u@KkYap{sQ2JS`W$N{aF`_a(#7(DVTq?U* zcB$fG#g){_w54a8fwc~?qL(ZeErHz1soYwBZf(F8l}XLWxpeg6(MzKjN3ZOh%qY3Q zOlRc=7FACzTIpZ3^24l^(~j)f6kt?m)2N(0!8Sm`0Xf@%wQd1T0#aKV+7?l_7MV9! zGPjmBZZ2hR7aNd?Ej2*M?Mj9)v}s%P%mBP@$>HvX?*20X;$&GxBY=lz5}?h(0*$7y zr+hqFSXC<}7IrhtmJkceeM;CM?)P9EgsY!Xh!;W2q{d&S)8B?&@Kr3Z9l)o63FOXe zVvo|w2rPpddr3#U3vs{rDZ*W0m5?mp6{w0WS9n*#!#$@s4IuKaLy`_ZK2U+B110L_ahRSB=WwVBKM; zMB#A70)!D8rr8bWJ_%++TnEF2hXo2bN`yzp9iUH1hVuDoK#X)p97E7v`v5>Dm9(&VTTz$2#d8dYWG#hFfn1Jo?9AaZ#E zX28CH=KmE|&7m(;FDv!<8ht6~#?|`krQw)`_|nnm6dHGp-V#bx^Yg_~OYKpVs_{-` zJi5l4l*MYimqQG(S5R~BB~e?H=#lv0(0Ko%jfFY%-e8)XJ#Gx>Jc;`Sc_mI0A~&_BEc<-Q;A6KVi*x(NY)5yi3qVcAYu_B zG$FDPT)ugeG^FD>vT=VGeO?3_LKC@70bk!AVan$Ls0|9rAS{CDWKiHmbbu1=4LJwlX5xR+igd=o20||wn zBmC34tqdgWWV#qg*v%Zqgx$;-CKP@;`KNWqFs$M@CVz%G3F3Qd#YrY4#tFA5$jW;) z@#VxFYx2E_Gh)3^_}mL zVli}NQa?#CK*&!V4Ei(EI-C(?U%OxyhsnMyn#W<}<{Czq8IHP`;CPD#3^&kEPPCJw zE><||k{IEri^iFXM=jdYK3NdnP)WM=3an}&>6U`I&_i#+a!1|Y1mGbVXuv`1H=s0r zZy<}j+JXTCy_LZAwS?~45H3j2Kts4A#0|3IM3))92WMxQPxhPZMHiQI-mG`oC0?s^Mje~nxj$Jk3_L|A6dd1mNlCk)J=!Ec^PwaQDbu<^G=?j z*-5=qXn>G+mNDperZumPK-=I_5=PrtW79VLJw4<|ubCX_B{%fICGFzz-q4ZWq>r`F zWD6o#QHSuTX`HBv3UNac@7uWvgK1&un?3NN2z?Vw*(BWWCH9<})2OqSJ>)@Piy6@ip$Vys!@x4|_McWtF;tSQ_QgPJbbsE4rfqX>o(j35|AFovKJ0WL2b zPD)}H9>0?7L(Bpq8|p1+n7b1^F^N(Bh8rI8gy~8&&@2}WG|SOIvrI71EaN#ItVOYa zNrdTZ@FqXYgz4*mIlB06yOEKx5(&!ZM;Ibw!wfiaT~j$(&1wZuswycw%4(Jb*r8OR znn9?&G!!oSLUjoQbe0$+BcPMSFepPqg))S*Lghfft-OUtD_@~16Fe&O#khqhDn626 z+}O!s19<|v8GJJ>2wD-e0dS`Af(|mFRP^+3A)cqF$uvcxnw+kymd)6?($^>w_vXPW z6)rm&6ECnHMu<}9&@{I-&-`n$FjNHg&#m*yAS zB&6e{ri#cWYa&aC!#L-RNFF8tt|6PPIfx*M)--Mrr_a1gIrrkD83prUq24l&F{jT#>t>=lJ#Q%iz=AVqSol$L3_T(l8uw!!HhqvOFT@ z`wBEyp#-dgfCvIgb>AH1%PYdJnS^Y-Oa^AG&0>>8QXw1HHJqM`zGopIf_b-CKp0t6fe8JDh>-S}+z8PR zLn1~FFpDh_QOVUrg-|{5O)-(^sX*6;<$}p-UVh!pwNPrFM>+>FE2#9 z*BP%Xo1@`2)}T!RO~8zJ{A67Z# zm~$8ieO-mxYGtA%k#okoXUY;@ugZKGbi59Irr3BRl>pNe?3! zxE70fLcbu7lO1J`kgp_^Ui2yR#W?;O6(32C2Ulw?h2mufuG`>oW-Eg281Yj8&U9Xw zM^+0JWtxf0-g}rbqD3oNlI)nofglq>h2R+-nv5?V3suEIUF${bOUcnJKEsSAr*reK6u-RUYSV|=E8b|j zZvVlSw+jQCpP1U*=ZAlr`h2V_FnH!Sa0*1%j7F@&kBfiWq-#Md)-7~9TCr}Y`_bHW zJJ_^BO5tY<|FlUrgn@NOG5s<6IDLao}VsJ!dv~A#5M3;ceeYZLVp}px$M4 zZDrKE8RoX-%)5&l+m#Op$S1!*>oRwJM~wBI{oFHci@7moj&W%a9(5H z-&#^D`7B!`G;8BVlmEOMlImOu?jl5$4Ias%pA5hy;8Bo@kVoxQr($`N0vHxJO0>Bq zZHq|NyO1+Yhq0;u0u?V5)5IGQ2rUvBjTP8e1JH_ao+%=uA)hLeBpE-U6k;^ymt`VG z1S&)-H4z~kQ(Q}!$S{o}9{*Q*E%93k;PS%ZwB&Hm#?Lk3RbgBqfF7uME>;4&$k%Xq z7}H7sYf-GnD7hlj;VS?Y(*Z+O4roQqD`+89x@swuMY@>w6MYkh@J>=&peAdm2GOVW z4V=({J|Yi}lY3GgV3ld?k;+s#atN{%T7<->%Eh=?Dk?uU`ens+MH>7|jG7IhD|W+p zv#4_M(JhLaHMpG^H5+9$s}F}3s=5dsL%h&vqGzcXA9{0N#F2wqc$Ev~6L_d1F@cPS zLgs+D2xCTrmr?RU5%QIZ<%WKh`C{-;QSp&@D03%=Oy0~c0K7QA3w>zxF|z}GID}?) z0&r&Xj1*ZwPGZz41T2CwTvW!<_bmjkA^0`|!Z{Jj%9x3`Y!q+u~Z=Z z+>G%P2>uAc^8i#lRuu$Au%8h2&=a`Uoq$F@nEga9@K%!5LpU$x$hx%c;x;_4cBOjK zQGB*_I>iylUNMzj?a!|EW!3oc4nMeucZuJ&I|H`L5NmZQ>0;7LDG)!MnnCVH zs`Ka8`EpkJQ{j665i=!TOnfOxmT9#=ceO8PjXxE>-4-*`FEdK7)=g$q`D|4S!ztlV zzF}!@Y|W+K%{8~JVBRfiM7{{Pqblmwas!0iTEU>dDs3|zfk(m-8pb0%43mwBstyHt z|EL+Gh~$yHl@e$43X&Dw&|~3*sUAXcpPRSyVPwv$xgiXUaAPY_Rtg;8#@0W;`HCBo z^6K7te_{Rg>Ph>0pLKmWVlcfQnBtZc6{IEFBzHtbg`)Lxn)_S$79NSBf;34ay4OL^ zL?F7gZ5q^XM54OU#B-q)6$(@~Xre;M?)WB%NOxaFOm4u4;n^WVcgLlpAfp@QHE|sf zE5i1!0&odObQ5HYX`QhF&xgglQw9sxCa^y@&VXM29XHM>!SRVK*Gvxp(Kv$)Miu4O zfCH2eXlTmH(`zAOjF5CHA@_5TPI*3zNV+1*xXJweJ`R7GZAQ!sEafupcx^MtXX&g} z3v%mY6x)nL&_Q8@iuTtX`Qz-#Yy$c20RL4-6FK@7@7ElcXxhXmg?W#fbkRPfqiCZ< zxZK2bdEp2b?)y0E)x-+2DPHaGWGY*YpBcD?E&c%(gEGKR%|(;{5gQw3IYP*^WwFOp z1rTZPA>!9X#1)&-e9)Nif!a5)vJ?av2-L3)10x8jm9MS4b$ferSH}m4z@K1A4^?`b zNUVc7B2N!%BT^0#?nzL#QBFsG2o04V2dnklYkgMX7Wnx$e@W!&KZ1}*Q+D9KF#yPf z3v#vPpGxc`it;YL14;flzj9m)A^sF-bZVkO=*f6iEs>i18+<{Fp*Mu@7hWk3q*M{J z=B0ky(kt*4btjrNSBHqrIegBK2u%ptNk)C#wC6I!Z4-dEpmlNH+aG>oKW{8thsMHX zg0XNJ8Vi>S#=@mMPFR^@36KQ7%V05h`~n3sjlmk$lOpBkXSf=>4Wq zj;!C*xA;Xb3um9o$;wjSIQM zH1|HFQOTiEuXVrcwK&l~LZmbcp9Y=7Hx+k3-1Y2OuQp}x{z zyfR=~C0Y7B^lSX3b9@2=6;0M1e!+iATEMY<%2DNaRDB4Wo^;WgblE@3rUSM$8Zp9W z0A>?3uJ9+{9=BF62s3w|2&hwA6WW~AEvI?&TIN0_w+r?^9YgJf3`?qKy*Yrw5Vr0`h%|3(bfw3fC9%F=XMZ92gjZnNVWT+}_#I z-q~tG1pWjvea6{9CGx-qCL-e3MZ^^};C!%w9Qm+=`fcHg9oO3uSie-o+fp=h4oW*s+{$6U_-a!K1QSq3&rg54HB6>7uG)j{Sq&;r^H8M_A(Kfg=F@W zXpp<-!_bJr?5WUz^P;;>47+j>i!SMvpz2@_+#FeK9)O#3Vuc3)=%9Kx(nT>f30fau zi<6zh+7z?mb9U}?b`Hi|$bHVvd8E!5`kbAU*;q-oMZnJCzAQVRf!o*2(+K(zum}z! zz*Tt$322d>Bg>tNox=r5&CZeK6hCVdotxu&F-b_VrP66>FmtugmQ; zwjG74l@j092D4yc`8Fhdh!QB6+SGIC z{_-y0j-4Q$@mY5fQd~hD%?G0cENTc<_?q{i=SU<(S0SR>r!&-u_G3AnxOAb2R*mL% zfBE)1@Qs2UKI@Lp3?CceJK@S(F;Stp3&--pak7dRoZRgii8hw&;~&dzzNCGK%`>>| zg=shEeYhrd9gBv{YD7j`zos6qW2B%b5f|-qHuH{4GH5P`2i=}XldmEEHv>{&Ea~aU zZw6l10}CI7PsgE%;5p%afBaB1VZAt*!bd z#S3plMCHqxs6?@03`0c_L>xs-Za_Qur8*>tNQ>v1QQRFl+&Os485bB1CnkpjI{x!S zzsA%YpwtYlabp`|$|btVNur%Pypciqd3ZjCKV!uEV;VwY{ffO~n zHcoZ5e2RmTwjjJkS~sdjRB{)E=O;?;Og2&VVK}tsRJjl~(2{CZBs|LEb=}lb%ClTd zBRjh!y&ot;s}D5J5Gl_fMaYM@9;lo$UyQR$QSp)F3)aq=ET}~$U%=&OW)Q&;f};qA z5sV-hLof=!nax{~;o718%GvX{I)`+|D=`UKB}4YHp`}twd5j8Xehr70h>mJJB z4c$m>DQweIxAf-C8O*Ju#?7hBZL48(Hg!AI03o+C81!eSZ7z$TBc8WIOxmA-P%+4l zTC|{T8K`WeBw4tO)J-=|rUl_&qF4fJGmxrgqbcw=vB^KsY%;7W4@}te*8vD33T?Vx z`#Jzs6Xj(6tJu_k5u3VT-xLs9B$C4T*`x?my|x%ig^@(m{~@AtLqunO%}B|004hXY z)&PJ4aHrAy9nSLP~ZI~=(m_edm|o8ih1rI z3)ZH_KR=cPz5Kgz zSa~c7Nw)~c!d<+$_j@?{??AE#I~J~aW2{6<0qI0Yr3KY}M7}W=_x>>5hdG+=!({?} zh7oiaW;maOe)6eJqR&VKeTL=ZLQPXgg{1mXQydY5;xb{nL~p!}ORqM)0fX^@H*X6$ z4MN23+FN%7@s+%Z@{RjlXr}y*_!_^x#%C2iGBf|?K^C&*l6Nd_;@`o!Isjc1E}DxV zr1?%I~)IgqN5z|LunM^+d2#(oOl1%9LS&#@)zpe4~ac8ktji$^<3g`*v%c(lVQ z9PM!O&BQXb_w?mZ$!Ao;_CWXeu!fkogyK%7a$&cGYRK3$ZwW==hsufRWVeLofs6(> zUX|0jxn3^c8ZC>E4~MtP$@4+3LRB<8%A`@$5OUHgCyVE$Rgy)GOj;#bU`1$|hLlVx zb&8PBscH;7D)YsVRz<}}l2#>j&Y*}*CarSg<4*xNGkAFvnY}7Xh=_r=K8oL?3np@|V`H3Wd%tJkNYFSiHtIex;+m5o3<|%z zIhtEN+0`a-r8x>~gg`{$x9Z;LxnB2H{hRe~v$uzC48d)GszVLm?fX_=z_d~lN+m}Y zN`>2~z_;0VUp#Q-_=k?=SC7BZeC^croqmPe1El z_uMQ+wa~42v1mJe052A8rw`&CqQXxL|FnJp!zx+4S9Fjb!h1z4hG=q~PJ!Q6FlDRo z+u(chcWre)!z*_9uyVhx{Ay3Yh8O$@!YJ#)38R{gEv3|tOU<_RwytL0tueGV zQtz%dK*+o681y%$wWTh!FiQJSx>6_ns3}8j(nQfli8TBlFvKH}hI*JC5c^PX(}^OA z(ms@~Y&A-vfXbK;NfdA2&gCM@QG3+G8k2~)1Tr1{e)7a z)lf$SJK!;5o1}v+Kz_B&oDOwHxZ37%6(TLL`U)(sI%W2qkD6rA-V2nClxPMA42#Eu zX3$n&shW*MLl!o9zSLJ>`-bmQn`+QjU#XfXCmV9HsSB^Z5?UnE4YzQ88Gr>MT=J!@ zzEWW%5f1r?&JA4Gh^}*9ZPJMPN`=TBO+=!ouhfVL7HLZm4~YPZOgaS7s8T+)--ZUH zV&;E`Ex}IU-UHv~L;&=J%7x6WK%9ZL>M9o|N|D4SM3e#_vl-X*S;S0GhK9IlC|isV z{ennD`2lCGd>Up~%6vqWLO)BN>tm@i@Ox4x3P_g5{G6hg(y8y9DS(FYL;&vjA`yUN zMs3jZV+{L*M8F!TBZ4Z4;|H=62k)y`Rb&;+0`HzGi}J^F_f$4g+CA4{cWNtRAZ8&s zZtdMu)ok27H)50LYxfjv`scEHs+uU@J)5zq3%`2`EfROn0M3@V?4Bx&q}>xNvKDst zR3Y-$nutW%J=KT^yXRKKBaYpZ`vO+@R{-iUM`+8$@XxnQSRYjG^DPs%OjN1xTPE&? z;+9Fql8SHs5XaXi+%oH-jtE<(n?Inm69;dMEwdL&3A0*wnBTe8wwna%RDR^=@!UF< zjg+=d7Q0p2IzKJOY|GnZLLE3x=CUoTS}EU_$FQjjzby+b61U}_c&N7J9e|cIF2hV5u<@U!dJfzCw*dN~(g*pbZA=SItU;Sb zz(bawQEQG=cnK;OVw1zJ;*=QXP?n+ekYDtvtRA%3;cPK&=r`hNAPpN0avJDJ*teCU zV`EgE9eTX5(VaU2B8TEoe~7-&`w+ghgvJuY$t*zd?q}kl3@yA0#rV*#(vl-WzNMk` zqEDGGh6PAed?c}jsdJ_XikDe{d;uP3&~kNV9KrJdoOa$8gscQAy6o>^?#j+4k);JQ zs=vCVGM80Z%DxXdR5w>PKu`o?jpMhtGq@h1Qt&}cWhFZg&5zVd$_~{*p?D4krKL+Y zwjZX!<&(;TL7`{SUZdD=E55=8Y-Q77AF!QGr0f||X_IMHvsnvh$x+a%r{2|@+cKDU zlN!NdDbUvtMN|7)&|L^^c77b8UmeE)=N-Q<{1@TU>4z zH`qTs=yh?yL{|2cgyUrsfS}nminc)g9>~JF1_s@OW1~G|-5v~JTH2bpW=xf_gLAQi z10IMJj#4-G4;*oEEf{GX9`ry7!&t97nB+b^a&T;TaDY5=2e78EBlr=5y9oXf!EX^* za4cscC_~VIpdA5jP8>OfM~uLU{S#5-5kVedO>iCr%^cjt##e0U89VA44Kl4=ZQOUT za6OhmZUyQ^-yb9R9s>N#GKcFYhsy_l@|nyQT;KUyCmJ+|Eq`ICw3pnM zYc3!EhWBoI*F@*fvnwazD{1vYHnbVnBKD}ewkv_4V z2mG_$G0`!do-xtM2a-pUCe1OiZJGc_24u0PL%LM^#8y6xJWAl6o=MxHn`no+5^d+5 zFFGfhr_Gj$mKeZjn%FdLO`6y|ZL(mFM95)HhDQnftYQ6IrEix0iqabjE@O!VpX2|-esMt{HTU7B81;6)tbfplqPnTyX_vMs*M8WU9O}fPp zwn5n*2=0<_r398Z{)n5cO#!E!9V3~$q(Qd?>javYils=R zOww^AQ%D~2Ag>;*AOq|I8xWvn0Oo6h7Xf%Z|dV(Ql4>m5tKEgp}Q1DcWF#LL3aa~2Fc(6NES07gO~*w!a-6~4#}Lu{BlYws$P6I z7SRLnf0%G1+LVpbZUYfzBvUgo(BGV3IYWa-8LW4=VNz(V{hvxKxme*A!KQvz$ zxqNYKY-H$KdDhS&Pg@~bFO%`7`s^%1)u7diXa`?-i%B6nm?P1T6j%z{4%o~K zZ=+0VWf0RK2d7mBzNb@ig&G-bwJ zT!+hoM?Py>4qGy^Mfj+5ntERj89^AM!VIs5}n zwR9t|6&*H1@;Fr1Br}wn#UQ#9x~EwreMNBh!m~&Q^HUJ86|rQEZN!snsi&#k_`p_t z-~cgvZ*AhW5U&rfOgF^X>f-WZ{o(WejXN*-SK`%1>SUe$HkRDy!S6p|B*cm9PhJV9 zzk~14D`CJOyR7=h7<9L|`%0F14V5XGp4lU{U&G;ZCu|aT$s4rxP*bmF{Xu(H92`ut zwJ>Ng*38j)3P^l6$5l|)kk!g>Q~v&7>i)Y38C03JDI7QfewcYcc{bZ=mxFR>W{-rQ zGhHSAk)oVqZU2TG$#^X)D1jsUeg{b717;* zc0~_#H%CD{Mz14XwfWD->oWDX&KA3ylW!e!2troeoqP|B znE(f)JgTyo&XL+9#Xt0a4*18u6Ev8?tj|u>kR3V}Hl4r<f<8ZkK2abjax{+=JL-=UC?#oi`^{LeqZKgxR#=~~mGoP!K3}t=IO^|$?^}V{ zR>Ldr12Iu{NNAkSh~QghQ-yNvldrnT4Wi zW%XiFDQMMqI$9KYY01#61*0e}Jy7xs#91#@CFQ+pRc0Kav!lbh9uBRS9L^73;fAb2 zX-K)C8mC}RmDBfBRXPuUACF3Yi*#Q1b-g0#vpKv_C`spWt5W*FSFMLuCG7PBebPb3 zNfMS(FqZaWpx%}R7=h^oGrCbwEQircgc=utJT>6fyl!ev&@7vlR&aPjQ*b_8)J%sp zOZlv2oQ4R70Ky5Va|YanMN95-F>Rb7O#?&>67e<>=Ri1&s$2I8`iFYav?|>$IlNi<7W6fHU?U%+e{%7LcxzX@ zvnAfy%r5LB^oaV1hR-y8oqRr}e@kzQci=varRf^;T8P#A*FV`7&eW&|$FGK#Lv>~) z>ZvPygA1?n%lu|ybcY*j8Dl%#CDQZcwr~pi3DMQ-%hx~uMJojKizaGxBbKNI8}Y;e z;`#pC#J6I+(UV-8dOG!Nx=uAt^sf)EkE|!*5{Zx0CmMY}T6^^L(ewFNee!pyx7IVy zZ+c*LkTVLkB9NJ0^e-VW1BtEhqMzNFY^ZyW~M)Jf{dcPZT?DrsE z{KH^fdG_NiE(N*8WG&icKn9k`FD(Wn#NT2-2GDs717f%U$i?5{Kem0H+pLcsV8zyx z0SD}$)nXH?#b|ABzgLE?!2Rl5fNv&84%U%!9LM0+Ljt&sIhIw}T#HHC0fDbQyu*Ws z+*wdu_G|Gibr&HQOx+3Q6)RgDuJ98jLo+2)v-Tv&FbOCQs)U_P<1*L=L4gNM(=r@} zGy(E(KJP?s=nB4(oi!Ar?DVLBX-i9kQ?__7?LjdJ4`BjQ9^yB1J7M=Z;f_P*n+QJw z?kkYeVMqig1a~`8jB!#&&ARW`7NFfr-XJe~?|J3DRLH>1br1x($$yF6yW+r>IPm<+ zH)mfaUjBMpoCJ&}l6Cw{u7zH6(c0pAAK(FRj1e?!rbf2JksWTdAtVR{cZI<%VQ};9 zOWVRY!DV7sIJYI7+hG0@`8x8=we5GVyjLnEhwCR_Wi`K? zUmw}-It2|4vByQv4E$7pw>qKzblM50(*+$boRmrP%mEFvRv8BvNee;dq2iHan9p@cYB< mYP=cqd+z<_pgu5efEPLBCb?_(0~AI5mzkg_AQ~dwNdE&&N#@-E diff --git a/HybroGen/__pycache__/ProxyDb.cpython-312.pyc b/HybroGen/__pycache__/ProxyDb.cpython-312.pyc deleted file mode 100644 index 2df604b604f4100964021bfaa25974867a3a4cb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15935 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 UEAx(4d^6*yTy%2MI<_wV4^^>3R{#J2 diff --git a/HybroGen/__pycache__/Register.cpython-312.pyc b/HybroGen/__pycache__/Register.cpython-312.pyc deleted file mode 100644 index 74ab688aefa4eac9e6bb2bf144a6f0f8fcfb40fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3665 zcmb_eO>7%Q6rNrGjbm@@{Is%DC*7n#>rf@Mil7t<0zm?oP|^t6PfhC~(0+YXFR(Bnf8#*5per;|AUq^0nIVkaAxwFqHZ=>RqGkhmxgLAP9W+)z zct}jLpfIwaGG!sa)H`G$$O3>N76c5l5MYFb0V#_BMi~X{VNt*s>j8|j7@)@DfW1ru zOt4jNC9^k)YgI%h5wEZgMOd!Lxs3MEs|m2~dT>6Xn`^Y$t?_49g< z4sBe|@%;5tZrOB)<}KSSS%q@R9m}nrC35Q90<*9Cmf4jR`A^qYOL-gq2u|tI^RCB) zcTf(%uVD)xtt;!q5DEl_Bk4u5L}1j~D|EP1G%=EQ)La>A=~UPU_t|VL0HcT;RY*2C z`}7}Z4w=qUhe{VX(U$d2Tv|B`zHu};5;nJ$^I)z+rKL`Ig@ey;IkaGXW#;WN&#F$) zGK<$Z9&Vu>y8iOapVa~m@iIs{&4Wm#h z*oIN7ynk7Ga78mETDs-r3BV!Nr~ zyTSWf1O9+?zomZAJS3gBR3VR**~bc}pv$T}0iBRt8+j5YoVaD$pUQZu9%(W6P9KGZ zRull(r^kRvFURvbnBa|zcsUOOFd;Xf_qQ9ZxM*wEl_zc_DWpR9AZUOrp5}yeD=TJ+ zx!j!~#&-w#1hABhF$StBIhyck((r#4+5slec%7!VXu3}IEvo-GxI^FAZ%-@!yL(pf z1m9v|lKes<@Hz-4Jv6??RIH}EF%+r{QpEoQio@XL9XfPiS}_l;2sf87 z-E*ip?xB@Afwa>5Y5mW)kLkj(pi9@rz=mnJR(04B0|!e*b*oO>OYyV-O!1KAWiFpJ(c3n%c6 zneSkMuKC=pahxPoi+>zVvR*;rGuI$ZMNxHCf0H z>JvWRjRtx|W^$)TxtgGF8iuZ>^{i{J za5eZE@ikY2-#%YsDt@?KJ>IRaN&O@363GT;Un=@jT#=24$DDZWh)*=f4q8vAjo2$8^s{vD3Id2%e4^75*56Ak=M-cFf z$nh)0@dLn5BTOP-UEv~+-$v;i!g~lJkUj$GaWj-eS?3r(0#L9n1Kc6c)kr9`m!zSQ zy+I{(VlS+OP9g~DHI&8?h7mFdBM74iV=YN&kKu5*5mZ91?c%6es1M@YX*?XmT5x$u f-*0;213m+Dm}nN7{w$y<%8T#?#RQikiY@;F;;H9V diff --git a/HybroGen/__pycache__/RegisterDescriptionLexer.cpython-312.pyc b/HybroGen/__pycache__/RegisterDescriptionLexer.cpython-312.pyc deleted file mode 100644 index 1364491876c2e13ca80d93616aa2c80b5e1b891d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5102 zcmcgwTTC3+8J;0JYDH<)hvuPAeXH^kYDY%XG;*3tOZ$@AjgtDQ|3AxO6FHiw zm3of&&i|kD?LX)I|GDyxrpXkfN#TR+4}ui+5h|s`tqXUSL3ouiD1**XZxR|MlA~vc zUX+;}qcbLRS}gtWUTLs(pcvelC`DNU{Ep9YGrZ2z)GY65LQyk>^OP1q>}7>hoca-2 zVKA$VDyUX^&ydr2~P%4)zm5^Ga z)dd(LIE^e(l-5>;bnoZL@bJ;26B8`ypUf-^q^qmjY1-dEnNDYx$r%_Yfy8+zcqlPW z9o8wH2JV0q^spRUgH4s57V@yh!#Y5xo-p7zFxH4DG$Tqah>Fv&4NGk&V(?MK@&Uxk zA+T9bNGO3?%@M@9lZXvlgibWNg+;BgNmwMLiAT9PESw=EEIQs7T3UtY2x*nEW$Shc zaNAatw?n9!pltKL+}4hD?K=>6L`0sD2)MQxw4EKoc0wN7rGWhKL)gBn3$dfK*t3p@ zQS01|*wul!yPFFs#Hs1tgW8@RQ6QuT+)l_Nk4ZRt$fJ*-_E;}suQ%G>y(sT3b08*! z>>Cs&3E6)@7$@YwpwLgq;|GNyLJkfJ$6(Cco_JC?PRNs<)^|vV6LQFt`=i1HA<-hM zB{nGNgbeIMiv#;TeB8q)JnSouZ=m1PVu*tkh(mFSB_w{B3p!0AIb4Nx!y`hFki;;` zi4nw+Bn$-{lpGaQLPo2x?#Q^%M##}Ii6i9LQK)gkWNZRk#*cY;9P#)G#EEgl6Hen( zTu>xW)uMLt6#i15l)(Q_>saG7O{TCs^|Xi2AU;!%m^y{%XfkQ*=p9ImpJGG^8e_o? zhjO{IRyJ?C;gnn399nwT znj17{?+M4u>8zbMt*B{dtn7R~J2#s!7fq{Ue#zBr)5@lES;sW`#*>x?b`|)u{{mkq zQ146Sm+C*GwsK7`+pD5-S-L2_TQPh?Ol&Ce8{**&zZj$;lwV*xZzJ5bRfzSactyOO`9nJw z?-DlMw!NnW5bi`_GJKDHl`<)vHYiw&l*yFNveObUzLKDwE47!-M4g9P!Q@YueT58a zi4&zRQu@cr+SIx@xI;WHcI!aCfBx@#I8bA|5^HFzvhA0bW4JB22YM zB&!jPk`rUD&_6md5=)M|OdLQQIG*fJ_Kn0`?pSQ_MA8+Ku@i}SGUoC}j>QJzPq{3% zMpTy_Po=s%-0fkvhkL9hFl;p=gb`X0S`oG)Y(v-%;8Z`rO&!xcNtd5n$j>k2Gxxvn z&^M^x`8~iZG`tI;ET)UhGWC7%>@vMfN^{10|2^P#cK-`8k2bxujIYH9JcXgQv_48y zDD$|1dTC?+V;~_dQ>hJ`25K8NJ#AwZEm0AYbhw_5y&c^V+2!nodDC*mR4O~0&8JeX znt9I5oS85!8@6$`+}p@u=N`+>EacMpIm>0z`B^t$n3*gx?D4tiK%ZNE#4?R+2DkqH zx!F9ttozeo$Q8gWoDB2ufwb3ZyGm-_#zGEdHI;gPA)Q-q34+VuI4qrgma7=|X&6MS3&54k*@YR? z0$;enl1s zW-rY=JD1C5)_E3;swf7ht@O-H+8W3fYh1=&vR&TJ8?aO?oO51aTx~sU88eqlr6Qb5 zI=Wms>k`AZ`jFKNVB@;zg7joDr0_o^%0lSI#&-a|JWqWn*IkzzZp!T|a{C+FwcvHR zx6uD#XYbpU#UNep9Jv`9T?vi;)O;;{wc*kuHzXh4^PYRnu7*z17(At3AKn_v?NCq&O~owe1TmJo(?BKS5O=p}oPr zU45ut_J$ZyTs}RU&sjY#$vuK292! z^QO9I?hVS?3ss&U?}`VC6Y-#hvmcIA%Erde7@DR(rmFr-)%=N)R~h~$Q@O%azTCIM jR9`9oBUAqY+xQ6^zRho=oBoxgchKQ03!hU^c&7gYNCm5C diff --git a/HybroGen/__pycache__/RegisterDescriptionListener.cpython-312.pyc b/HybroGen/__pycache__/RegisterDescriptionListener.cpython-312.pyc deleted file mode 100644 index 293a801a5bf5a3c6c7683581292734a4ad06a13b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6685 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 Y<0?bxqaMSyOhdu7bw8)@mw=i74}rGB2LJ#7 diff --git a/HybroGen/__pycache__/__init__.cpython-312.pyc b/HybroGen/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 207e223619ebe21ba65ef94088f485ccdb103779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmX@j%ge<81Y74`&jitrK?FMZ%mNgd&QQsq$>_I|p@<2{`wUX^%TPZfKQ}ceKRGc+ zzcAOx!obADNZ+F}sVLt)H4njvkI&4@EQycTE2#X%VUwGmQks)$SHuc5ff0y{L5z>g LjEsy$%s>_Z2IwKN diff --git a/HybroLang/HybroLang.interp b/HybroLang/HybroLang.interp deleted file mode 100644 index 4f98fb4..0000000 --- a/HybroLang/HybroLang.interp +++ /dev/null @@ -1,125 +0,0 @@ -token literal names: -null -'(' -')' -'{' -'}' -',' -';' -'for' -'if' -'else' -'return' -'=' -'[' -']' -'*' -'/' -'+' -'-' -'<<' -'>>' -'&' -'|' -'^' -'int' -'uint' -'sint' -'suint' -'flt' -'cpl' -'pix' -'ipv4' -'ipv6' -'[]' -'==' -'!=' -'<' -'>' -'<=' -'>=' -null -null -null -null -null -null -null -null - -token symbolic names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -DecimalFloatingConstant -IntegerConstant -DecimalConstant -Name -INLINE -WhiteSpace -LineComment -NewLine - -rule names: -compilationunit -function -fndcl -fnprototype -fnbody -paramdcllist -localvardef -vardcllist -vardcl -actionlist -condexpr -action -returnexpr -affectexpr -unaryexpr -varorvalue -datatype -intconstvalue -constvalue -constinline -typebase -condOperator - - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 48, 206, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 3, 2, 6, 2, 48, 10, 2, 13, 2, 14, 2, 49, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 7, 6, 65, 10, 6, 12, 6, 14, 6, 68, 11, 6, 3, 6, 3, 6, 5, 6, 72, 10, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 7, 7, 79, 10, 7, 12, 7, 14, 7, 82, 11, 7, 3, 7, 5, 7, 85, 10, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 7, 9, 93, 10, 9, 12, 9, 14, 9, 96, 11, 9, 3, 10, 3, 10, 3, 10, 3, 11, 7, 11, 102, 10, 11, 12, 11, 14, 11, 105, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 138, 10, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 5, 15, 154, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 7, 16, 171, 10, 16, 12, 16, 14, 16, 174, 11, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 183, 10, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 191, 10, 19, 3, 20, 3, 20, 3, 20, 5, 20, 196, 10, 20, 3, 21, 3, 21, 3, 22, 3, 22, 5, 22, 202, 10, 22, 3, 23, 3, 23, 3, 23, 2, 3, 30, 24, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 2, 8, 3, 2, 16, 17, 3, 2, 18, 19, 3, 2, 20, 21, 3, 2, 22, 24, 3, 2, 25, 33, 3, 2, 35, 40, 2, 203, 2, 47, 3, 2, 2, 2, 4, 51, 3, 2, 2, 2, 6, 54, 3, 2, 2, 2, 8, 58, 3, 2, 2, 2, 10, 62, 3, 2, 2, 2, 12, 84, 3, 2, 2, 2, 14, 86, 3, 2, 2, 2, 16, 89, 3, 2, 2, 2, 18, 97, 3, 2, 2, 2, 20, 103, 3, 2, 2, 2, 22, 106, 3, 2, 2, 2, 24, 137, 3, 2, 2, 2, 26, 139, 3, 2, 2, 2, 28, 153, 3, 2, 2, 2, 30, 155, 3, 2, 2, 2, 32, 182, 3, 2, 2, 2, 34, 184, 3, 2, 2, 2, 36, 190, 3, 2, 2, 2, 38, 195, 3, 2, 2, 2, 40, 197, 3, 2, 2, 2, 42, 199, 3, 2, 2, 2, 44, 203, 3, 2, 2, 2, 46, 48, 5, 4, 3, 2, 47, 46, 3, 2, 2, 2, 48, 49, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 49, 50, 3, 2, 2, 2, 50, 3, 3, 2, 2, 2, 51, 52, 5, 6, 4, 2, 52, 53, 5, 10, 6, 2, 53, 5, 3, 2, 2, 2, 54, 55, 5, 34, 18, 2, 55, 56, 7, 44, 2, 2, 56, 57, 5, 8, 5, 2, 57, 7, 3, 2, 2, 2, 58, 59, 7, 3, 2, 2, 59, 60, 5, 12, 7, 2, 60, 61, 7, 4, 2, 2, 61, 9, 3, 2, 2, 2, 62, 66, 7, 5, 2, 2, 63, 65, 5, 14, 8, 2, 64, 63, 3, 2, 2, 2, 65, 68, 3, 2, 2, 2, 66, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 69, 3, 2, 2, 2, 68, 66, 3, 2, 2, 2, 69, 71, 5, 20, 11, 2, 70, 72, 5, 26, 14, 2, 71, 70, 3, 2, 2, 2, 71, 72, 3, 2, 2, 2, 72, 73, 3, 2, 2, 2, 73, 74, 7, 6, 2, 2, 74, 11, 3, 2, 2, 2, 75, 80, 5, 18, 10, 2, 76, 77, 7, 7, 2, 2, 77, 79, 5, 18, 10, 2, 78, 76, 3, 2, 2, 2, 79, 82, 3, 2, 2, 2, 80, 78, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 85, 3, 2, 2, 2, 82, 80, 3, 2, 2, 2, 83, 85, 3, 2, 2, 2, 84, 75, 3, 2, 2, 2, 84, 83, 3, 2, 2, 2, 85, 13, 3, 2, 2, 2, 86, 87, 5, 16, 9, 2, 87, 88, 7, 8, 2, 2, 88, 15, 3, 2, 2, 2, 89, 94, 5, 18, 10, 2, 90, 91, 7, 7, 2, 2, 91, 93, 7, 44, 2, 2, 92, 90, 3, 2, 2, 2, 93, 96, 3, 2, 2, 2, 94, 92, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 17, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 97, 98, 5, 34, 18, 2, 98, 99, 7, 44, 2, 2, 99, 19, 3, 2, 2, 2, 100, 102, 5, 24, 13, 2, 101, 100, 3, 2, 2, 2, 102, 105, 3, 2, 2, 2, 103, 101, 3, 2, 2, 2, 103, 104, 3, 2, 2, 2, 104, 21, 3, 2, 2, 2, 105, 103, 3, 2, 2, 2, 106, 107, 5, 32, 17, 2, 107, 108, 5, 44, 23, 2, 108, 109, 5, 32, 17, 2, 109, 23, 3, 2, 2, 2, 110, 111, 5, 28, 15, 2, 111, 112, 7, 8, 2, 2, 112, 138, 3, 2, 2, 2, 113, 114, 7, 9, 2, 2, 114, 115, 7, 3, 2, 2, 115, 116, 5, 28, 15, 2, 116, 117, 7, 8, 2, 2, 117, 118, 5, 22, 12, 2, 118, 119, 7, 8, 2, 2, 119, 120, 5, 28, 15, 2, 120, 121, 7, 4, 2, 2, 121, 122, 7, 5, 2, 2, 122, 123, 5, 20, 11, 2, 123, 124, 7, 6, 2, 2, 124, 138, 3, 2, 2, 2, 125, 126, 7, 10, 2, 2, 126, 127, 7, 3, 2, 2, 127, 128, 5, 22, 12, 2, 128, 129, 7, 4, 2, 2, 129, 130, 7, 5, 2, 2, 130, 131, 5, 20, 11, 2, 131, 132, 7, 6, 2, 2, 132, 133, 7, 11, 2, 2, 133, 134, 7, 5, 2, 2, 134, 135, 5, 20, 11, 2, 135, 136, 7, 6, 2, 2, 136, 138, 3, 2, 2, 2, 137, 110, 3, 2, 2, 2, 137, 113, 3, 2, 2, 2, 137, 125, 3, 2, 2, 2, 138, 25, 3, 2, 2, 2, 139, 140, 7, 12, 2, 2, 140, 141, 5, 30, 16, 2, 141, 142, 7, 8, 2, 2, 142, 27, 3, 2, 2, 2, 143, 144, 7, 44, 2, 2, 144, 145, 7, 13, 2, 2, 145, 154, 5, 30, 16, 2, 146, 147, 7, 44, 2, 2, 147, 148, 7, 14, 2, 2, 148, 149, 5, 30, 16, 2, 149, 150, 7, 15, 2, 2, 150, 151, 7, 13, 2, 2, 151, 152, 5, 30, 16, 2, 152, 154, 3, 2, 2, 2, 153, 143, 3, 2, 2, 2, 153, 146, 3, 2, 2, 2, 154, 29, 3, 2, 2, 2, 155, 156, 8, 16, 1, 2, 156, 157, 5, 32, 17, 2, 157, 172, 3, 2, 2, 2, 158, 159, 12, 7, 2, 2, 159, 160, 9, 2, 2, 2, 160, 171, 5, 30, 16, 8, 161, 162, 12, 6, 2, 2, 162, 163, 9, 3, 2, 2, 163, 171, 5, 30, 16, 7, 164, 165, 12, 5, 2, 2, 165, 166, 9, 4, 2, 2, 166, 171, 5, 30, 16, 6, 167, 168, 12, 4, 2, 2, 168, 169, 9, 5, 2, 2, 169, 171, 5, 30, 16, 5, 170, 158, 3, 2, 2, 2, 170, 161, 3, 2, 2, 2, 170, 164, 3, 2, 2, 2, 170, 167, 3, 2, 2, 2, 171, 174, 3, 2, 2, 2, 172, 170, 3, 2, 2, 2, 172, 173, 3, 2, 2, 2, 173, 31, 3, 2, 2, 2, 174, 172, 3, 2, 2, 2, 175, 176, 7, 44, 2, 2, 176, 177, 7, 14, 2, 2, 177, 178, 5, 30, 16, 2, 178, 179, 7, 15, 2, 2, 179, 183, 3, 2, 2, 2, 180, 183, 5, 38, 20, 2, 181, 183, 7, 44, 2, 2, 182, 175, 3, 2, 2, 2, 182, 180, 3, 2, 2, 2, 182, 181, 3, 2, 2, 2, 183, 33, 3, 2, 2, 2, 184, 185, 5, 42, 22, 2, 185, 186, 5, 36, 19, 2, 186, 187, 5, 36, 19, 2, 187, 35, 3, 2, 2, 2, 188, 191, 7, 42, 2, 2, 189, 191, 5, 40, 21, 2, 190, 188, 3, 2, 2, 2, 190, 189, 3, 2, 2, 2, 191, 37, 3, 2, 2, 2, 192, 196, 7, 42, 2, 2, 193, 196, 7, 41, 2, 2, 194, 196, 5, 40, 21, 2, 195, 192, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 195, 194, 3, 2, 2, 2, 196, 39, 3, 2, 2, 2, 197, 198, 7, 45, 2, 2, 198, 41, 3, 2, 2, 2, 199, 201, 9, 6, 2, 2, 200, 202, 7, 34, 2, 2, 201, 200, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 43, 3, 2, 2, 2, 203, 204, 9, 7, 2, 2, 204, 45, 3, 2, 2, 2, 17, 49, 66, 71, 80, 84, 94, 103, 137, 153, 170, 172, 182, 190, 195, 201] \ No newline at end of file diff --git a/HybroLang/HybroLang.tokens b/HybroLang/HybroLang.tokens deleted file mode 100644 index 574a34a..0000000 --- a/HybroLang/HybroLang.tokens +++ /dev/null @@ -1,84 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -T__4=5 -T__5=6 -T__6=7 -T__7=8 -T__8=9 -T__9=10 -T__10=11 -T__11=12 -T__12=13 -T__13=14 -T__14=15 -T__15=16 -T__16=17 -T__17=18 -T__18=19 -T__19=20 -T__20=21 -T__21=22 -T__22=23 -T__23=24 -T__24=25 -T__25=26 -T__26=27 -T__27=28 -T__28=29 -T__29=30 -T__30=31 -T__31=32 -T__32=33 -T__33=34 -T__34=35 -T__35=36 -T__36=37 -T__37=38 -DecimalFloatingConstant=39 -IntegerConstant=40 -DecimalConstant=41 -Name=42 -INLINE=43 -WhiteSpace=44 -LineComment=45 -NewLine=46 -'('=1 -')'=2 -'{'=3 -'}'=4 -','=5 -';'=6 -'for'=7 -'if'=8 -'else'=9 -'return'=10 -'='=11 -'['=12 -']'=13 -'*'=14 -'/'=15 -'+'=16 -'-'=17 -'<<'=18 -'>>'=19 -'&'=20 -'|'=21 -'^'=22 -'int'=23 -'uint'=24 -'sint'=25 -'suint'=26 -'flt'=27 -'cpl'=28 -'pix'=29 -'ipv4'=30 -'ipv6'=31 -'[]'=32 -'=='=33 -'!='=34 -'<'=35 -'>'=36 -'<='=37 -'>='=38 diff --git a/HybroLang/HybroLangLexer.interp b/HybroLang/HybroLangLexer.interp deleted file mode 100644 index 49e7b7c..0000000 --- a/HybroLang/HybroLangLexer.interp +++ /dev/null @@ -1,162 +0,0 @@ -token literal names: -null -'(' -')' -'{' -'}' -',' -';' -'for' -'if' -'else' -'return' -'=' -'[' -']' -'*' -'/' -'+' -'-' -'<<' -'>>' -'&' -'|' -'^' -'int' -'uint' -'sint' -'suint' -'flt' -'cpl' -'pix' -'ipv4' -'ipv6' -'[]' -'==' -'!=' -'<' -'>' -'<=' -'>=' -null -null -null -null -null -null -null -null - -token symbolic names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -DecimalFloatingConstant -IntegerConstant -DecimalConstant -Name -INLINE -WhiteSpace -LineComment -NewLine - -rule names: -T__0 -T__1 -T__2 -T__3 -T__4 -T__5 -T__6 -T__7 -T__8 -T__9 -T__10 -T__11 -T__12 -T__13 -T__14 -T__15 -T__16 -T__17 -T__18 -T__19 -T__20 -T__21 -T__22 -T__23 -T__24 -T__25 -T__26 -T__27 -T__28 -T__29 -T__30 -T__31 -T__32 -T__33 -T__34 -T__35 -T__36 -T__37 -DecimalFloatingConstant -ExponentPart -FloatingSuffix -FractionalConstant -IntegerConstant -DecimalConstant -DigitSequence -Digit -NonzeroDigit -Sign -Name -INLINE -WhiteSpace -LineComment -NewLine - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 48, 322, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 5, 40, 230, 10, 40, 3, 40, 5, 40, 233, 10, 40, 3, 41, 3, 41, 5, 41, 237, 10, 41, 3, 41, 3, 41, 3, 41, 5, 41, 242, 10, 41, 3, 41, 5, 41, 245, 10, 41, 3, 42, 3, 42, 3, 43, 5, 43, 250, 10, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 257, 10, 43, 3, 44, 3, 44, 3, 45, 3, 45, 7, 45, 263, 10, 45, 12, 45, 14, 45, 266, 11, 45, 3, 46, 6, 46, 269, 10, 46, 13, 46, 14, 46, 270, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 7, 50, 281, 10, 50, 12, 50, 14, 50, 284, 11, 50, 3, 51, 3, 51, 3, 51, 3, 51, 6, 51, 290, 10, 51, 13, 51, 14, 51, 291, 3, 51, 3, 51, 3, 52, 6, 52, 297, 10, 52, 13, 52, 14, 52, 298, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 7, 53, 307, 10, 53, 12, 53, 14, 53, 310, 11, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 5, 54, 317, 10, 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 308, 2, 55, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 2, 83, 2, 85, 2, 87, 42, 89, 43, 91, 2, 93, 2, 95, 2, 97, 2, 99, 44, 101, 45, 103, 46, 105, 47, 107, 48, 3, 2, 10, 6, 2, 72, 72, 78, 78, 104, 104, 110, 110, 3, 2, 50, 59, 3, 2, 51, 59, 4, 2, 45, 45, 47, 47, 4, 2, 67, 92, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 43, 43, 4, 2, 11, 11, 34, 34, 2, 328, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 3, 109, 3, 2, 2, 2, 5, 111, 3, 2, 2, 2, 7, 113, 3, 2, 2, 2, 9, 115, 3, 2, 2, 2, 11, 117, 3, 2, 2, 2, 13, 119, 3, 2, 2, 2, 15, 121, 3, 2, 2, 2, 17, 125, 3, 2, 2, 2, 19, 128, 3, 2, 2, 2, 21, 133, 3, 2, 2, 2, 23, 140, 3, 2, 2, 2, 25, 142, 3, 2, 2, 2, 27, 144, 3, 2, 2, 2, 29, 146, 3, 2, 2, 2, 31, 148, 3, 2, 2, 2, 33, 150, 3, 2, 2, 2, 35, 152, 3, 2, 2, 2, 37, 154, 3, 2, 2, 2, 39, 157, 3, 2, 2, 2, 41, 160, 3, 2, 2, 2, 43, 162, 3, 2, 2, 2, 45, 164, 3, 2, 2, 2, 47, 166, 3, 2, 2, 2, 49, 170, 3, 2, 2, 2, 51, 175, 3, 2, 2, 2, 53, 180, 3, 2, 2, 2, 55, 186, 3, 2, 2, 2, 57, 190, 3, 2, 2, 2, 59, 194, 3, 2, 2, 2, 61, 198, 3, 2, 2, 2, 63, 203, 3, 2, 2, 2, 65, 208, 3, 2, 2, 2, 67, 211, 3, 2, 2, 2, 69, 214, 3, 2, 2, 2, 71, 217, 3, 2, 2, 2, 73, 219, 3, 2, 2, 2, 75, 221, 3, 2, 2, 2, 77, 224, 3, 2, 2, 2, 79, 227, 3, 2, 2, 2, 81, 244, 3, 2, 2, 2, 83, 246, 3, 2, 2, 2, 85, 256, 3, 2, 2, 2, 87, 258, 3, 2, 2, 2, 89, 260, 3, 2, 2, 2, 91, 268, 3, 2, 2, 2, 93, 272, 3, 2, 2, 2, 95, 274, 3, 2, 2, 2, 97, 276, 3, 2, 2, 2, 99, 278, 3, 2, 2, 2, 101, 285, 3, 2, 2, 2, 103, 296, 3, 2, 2, 2, 105, 302, 3, 2, 2, 2, 107, 316, 3, 2, 2, 2, 109, 110, 7, 42, 2, 2, 110, 4, 3, 2, 2, 2, 111, 112, 7, 43, 2, 2, 112, 6, 3, 2, 2, 2, 113, 114, 7, 125, 2, 2, 114, 8, 3, 2, 2, 2, 115, 116, 7, 127, 2, 2, 116, 10, 3, 2, 2, 2, 117, 118, 7, 46, 2, 2, 118, 12, 3, 2, 2, 2, 119, 120, 7, 61, 2, 2, 120, 14, 3, 2, 2, 2, 121, 122, 7, 104, 2, 2, 122, 123, 7, 113, 2, 2, 123, 124, 7, 116, 2, 2, 124, 16, 3, 2, 2, 2, 125, 126, 7, 107, 2, 2, 126, 127, 7, 104, 2, 2, 127, 18, 3, 2, 2, 2, 128, 129, 7, 103, 2, 2, 129, 130, 7, 110, 2, 2, 130, 131, 7, 117, 2, 2, 131, 132, 7, 103, 2, 2, 132, 20, 3, 2, 2, 2, 133, 134, 7, 116, 2, 2, 134, 135, 7, 103, 2, 2, 135, 136, 7, 118, 2, 2, 136, 137, 7, 119, 2, 2, 137, 138, 7, 116, 2, 2, 138, 139, 7, 112, 2, 2, 139, 22, 3, 2, 2, 2, 140, 141, 7, 63, 2, 2, 141, 24, 3, 2, 2, 2, 142, 143, 7, 93, 2, 2, 143, 26, 3, 2, 2, 2, 144, 145, 7, 95, 2, 2, 145, 28, 3, 2, 2, 2, 146, 147, 7, 44, 2, 2, 147, 30, 3, 2, 2, 2, 148, 149, 7, 49, 2, 2, 149, 32, 3, 2, 2, 2, 150, 151, 7, 45, 2, 2, 151, 34, 3, 2, 2, 2, 152, 153, 7, 47, 2, 2, 153, 36, 3, 2, 2, 2, 154, 155, 7, 62, 2, 2, 155, 156, 7, 62, 2, 2, 156, 38, 3, 2, 2, 2, 157, 158, 7, 64, 2, 2, 158, 159, 7, 64, 2, 2, 159, 40, 3, 2, 2, 2, 160, 161, 7, 40, 2, 2, 161, 42, 3, 2, 2, 2, 162, 163, 7, 126, 2, 2, 163, 44, 3, 2, 2, 2, 164, 165, 7, 96, 2, 2, 165, 46, 3, 2, 2, 2, 166, 167, 7, 107, 2, 2, 167, 168, 7, 112, 2, 2, 168, 169, 7, 118, 2, 2, 169, 48, 3, 2, 2, 2, 170, 171, 7, 119, 2, 2, 171, 172, 7, 107, 2, 2, 172, 173, 7, 112, 2, 2, 173, 174, 7, 118, 2, 2, 174, 50, 3, 2, 2, 2, 175, 176, 7, 117, 2, 2, 176, 177, 7, 107, 2, 2, 177, 178, 7, 112, 2, 2, 178, 179, 7, 118, 2, 2, 179, 52, 3, 2, 2, 2, 180, 181, 7, 117, 2, 2, 181, 182, 7, 119, 2, 2, 182, 183, 7, 107, 2, 2, 183, 184, 7, 112, 2, 2, 184, 185, 7, 118, 2, 2, 185, 54, 3, 2, 2, 2, 186, 187, 7, 104, 2, 2, 187, 188, 7, 110, 2, 2, 188, 189, 7, 118, 2, 2, 189, 56, 3, 2, 2, 2, 190, 191, 7, 101, 2, 2, 191, 192, 7, 114, 2, 2, 192, 193, 7, 110, 2, 2, 193, 58, 3, 2, 2, 2, 194, 195, 7, 114, 2, 2, 195, 196, 7, 107, 2, 2, 196, 197, 7, 122, 2, 2, 197, 60, 3, 2, 2, 2, 198, 199, 7, 107, 2, 2, 199, 200, 7, 114, 2, 2, 200, 201, 7, 120, 2, 2, 201, 202, 7, 54, 2, 2, 202, 62, 3, 2, 2, 2, 203, 204, 7, 107, 2, 2, 204, 205, 7, 114, 2, 2, 205, 206, 7, 120, 2, 2, 206, 207, 7, 56, 2, 2, 207, 64, 3, 2, 2, 2, 208, 209, 7, 93, 2, 2, 209, 210, 7, 95, 2, 2, 210, 66, 3, 2, 2, 2, 211, 212, 7, 63, 2, 2, 212, 213, 7, 63, 2, 2, 213, 68, 3, 2, 2, 2, 214, 215, 7, 35, 2, 2, 215, 216, 7, 63, 2, 2, 216, 70, 3, 2, 2, 2, 217, 218, 7, 62, 2, 2, 218, 72, 3, 2, 2, 2, 219, 220, 7, 64, 2, 2, 220, 74, 3, 2, 2, 2, 221, 222, 7, 62, 2, 2, 222, 223, 7, 63, 2, 2, 223, 76, 3, 2, 2, 2, 224, 225, 7, 64, 2, 2, 225, 226, 7, 63, 2, 2, 226, 78, 3, 2, 2, 2, 227, 229, 5, 85, 43, 2, 228, 230, 5, 81, 41, 2, 229, 228, 3, 2, 2, 2, 229, 230, 3, 2, 2, 2, 230, 232, 3, 2, 2, 2, 231, 233, 5, 83, 42, 2, 232, 231, 3, 2, 2, 2, 232, 233, 3, 2, 2, 2, 233, 80, 3, 2, 2, 2, 234, 236, 7, 103, 2, 2, 235, 237, 5, 97, 49, 2, 236, 235, 3, 2, 2, 2, 236, 237, 3, 2, 2, 2, 237, 238, 3, 2, 2, 2, 238, 245, 5, 91, 46, 2, 239, 241, 7, 71, 2, 2, 240, 242, 5, 97, 49, 2, 241, 240, 3, 2, 2, 2, 241, 242, 3, 2, 2, 2, 242, 243, 3, 2, 2, 2, 243, 245, 5, 91, 46, 2, 244, 234, 3, 2, 2, 2, 244, 239, 3, 2, 2, 2, 245, 82, 3, 2, 2, 2, 246, 247, 9, 2, 2, 2, 247, 84, 3, 2, 2, 2, 248, 250, 5, 91, 46, 2, 249, 248, 3, 2, 2, 2, 249, 250, 3, 2, 2, 2, 250, 251, 3, 2, 2, 2, 251, 252, 7, 48, 2, 2, 252, 257, 5, 91, 46, 2, 253, 254, 5, 91, 46, 2, 254, 255, 7, 48, 2, 2, 255, 257, 3, 2, 2, 2, 256, 249, 3, 2, 2, 2, 256, 253, 3, 2, 2, 2, 257, 86, 3, 2, 2, 2, 258, 259, 5, 91, 46, 2, 259, 88, 3, 2, 2, 2, 260, 264, 5, 95, 48, 2, 261, 263, 5, 93, 47, 2, 262, 261, 3, 2, 2, 2, 263, 266, 3, 2, 2, 2, 264, 262, 3, 2, 2, 2, 264, 265, 3, 2, 2, 2, 265, 90, 3, 2, 2, 2, 266, 264, 3, 2, 2, 2, 267, 269, 5, 93, 47, 2, 268, 267, 3, 2, 2, 2, 269, 270, 3, 2, 2, 2, 270, 268, 3, 2, 2, 2, 270, 271, 3, 2, 2, 2, 271, 92, 3, 2, 2, 2, 272, 273, 9, 3, 2, 2, 273, 94, 3, 2, 2, 2, 274, 275, 9, 4, 2, 2, 275, 96, 3, 2, 2, 2, 276, 277, 9, 5, 2, 2, 277, 98, 3, 2, 2, 2, 278, 282, 9, 6, 2, 2, 279, 281, 9, 7, 2, 2, 280, 279, 3, 2, 2, 2, 281, 284, 3, 2, 2, 2, 282, 280, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, 100, 3, 2, 2, 2, 284, 282, 3, 2, 2, 2, 285, 286, 7, 37, 2, 2, 286, 287, 7, 42, 2, 2, 287, 289, 3, 2, 2, 2, 288, 290, 10, 8, 2, 2, 289, 288, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 289, 3, 2, 2, 2, 291, 292, 3, 2, 2, 2, 292, 293, 3, 2, 2, 2, 293, 294, 7, 43, 2, 2, 294, 102, 3, 2, 2, 2, 295, 297, 9, 9, 2, 2, 296, 295, 3, 2, 2, 2, 297, 298, 3, 2, 2, 2, 298, 296, 3, 2, 2, 2, 298, 299, 3, 2, 2, 2, 299, 300, 3, 2, 2, 2, 300, 301, 8, 52, 2, 2, 301, 104, 3, 2, 2, 2, 302, 303, 7, 49, 2, 2, 303, 304, 7, 49, 2, 2, 304, 308, 3, 2, 2, 2, 305, 307, 11, 2, 2, 2, 306, 305, 3, 2, 2, 2, 307, 310, 3, 2, 2, 2, 308, 309, 3, 2, 2, 2, 308, 306, 3, 2, 2, 2, 309, 311, 3, 2, 2, 2, 310, 308, 3, 2, 2, 2, 311, 312, 5, 107, 54, 2, 312, 313, 3, 2, 2, 2, 313, 314, 8, 53, 2, 2, 314, 106, 3, 2, 2, 2, 315, 317, 7, 15, 2, 2, 316, 315, 3, 2, 2, 2, 316, 317, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 319, 7, 12, 2, 2, 319, 320, 3, 2, 2, 2, 320, 321, 8, 54, 2, 2, 321, 108, 3, 2, 2, 2, 17, 2, 229, 232, 236, 241, 244, 249, 256, 264, 270, 282, 291, 298, 308, 316, 3, 8, 2, 2] \ No newline at end of file diff --git a/HybroLang/HybroLangLexer.py b/HybroLang/HybroLangLexer.py deleted file mode 100644 index e628c3e..0000000 --- a/HybroLang/HybroLangLexer.py +++ /dev/null @@ -1,240 +0,0 @@ -# Generated from HybroLang.g4 by ANTLR 4.9.2 -from antlr4 import * -from io import StringIO -import sys -if sys.version_info[1] > 5: - from typing import TextIO -else: - from typing.io import TextIO - - -def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\60") - buf.write("\u0142\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7") - buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r") - buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23") - buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30") - buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36") - buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%") - buf.write("\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.") - buf.write("\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64") - buf.write("\t\64\4\65\t\65\4\66\t\66\3\2\3\2\3\3\3\3\3\4\3\4\3\5") - buf.write("\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\n\3") - buf.write("\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f") - buf.write("\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21\3") - buf.write("\22\3\22\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26") - buf.write("\3\26\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31") - buf.write("\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33") - buf.write("\3\33\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36") - buf.write("\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3!") - buf.write("\3!\3!\3\"\3\"\3\"\3#\3#\3#\3$\3$\3%\3%\3&\3&\3&\3\'\3") - buf.write("\'\3\'\3(\3(\5(\u00e6\n(\3(\5(\u00e9\n(\3)\3)\5)\u00ed") - buf.write("\n)\3)\3)\3)\5)\u00f2\n)\3)\5)\u00f5\n)\3*\3*\3+\5+\u00fa") - buf.write("\n+\3+\3+\3+\3+\3+\5+\u0101\n+\3,\3,\3-\3-\7-\u0107\n") - buf.write("-\f-\16-\u010a\13-\3.\6.\u010d\n.\r.\16.\u010e\3/\3/\3") - buf.write("\60\3\60\3\61\3\61\3\62\3\62\7\62\u0119\n\62\f\62\16\62") - buf.write("\u011c\13\62\3\63\3\63\3\63\3\63\6\63\u0122\n\63\r\63") - buf.write("\16\63\u0123\3\63\3\63\3\64\6\64\u0129\n\64\r\64\16\64") - buf.write("\u012a\3\64\3\64\3\65\3\65\3\65\3\65\7\65\u0133\n\65\f") - buf.write("\65\16\65\u0136\13\65\3\65\3\65\3\65\3\65\3\66\5\66\u013d") - buf.write("\n\66\3\66\3\66\3\66\3\66\3\u0134\2\67\3\3\5\4\7\5\t\6") - buf.write("\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20") - buf.write("\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65") - buf.write("\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q\2S\2U\2W*Y+[") - buf.write("\2]\2_\2a\2c,e-g.i/k\60\3\2\n\6\2HHNNhhnn\3\2\62;\3\2") - buf.write("\63;\4\2--//\4\2C\\c|\6\2\62;C\\aac|\3\2++\4\2\13\13\"") - buf.write("\"\2\u0148\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2") - buf.write("\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2") - buf.write("\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2") - buf.write("\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#") - buf.write("\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2") - buf.write("\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65") - buf.write("\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2") - buf.write("\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2") - buf.write("\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2W\3\2") - buf.write("\2\2\2Y\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3") - buf.write("\2\2\2\2k\3\2\2\2\3m\3\2\2\2\5o\3\2\2\2\7q\3\2\2\2\ts") - buf.write("\3\2\2\2\13u\3\2\2\2\rw\3\2\2\2\17y\3\2\2\2\21}\3\2\2") - buf.write("\2\23\u0080\3\2\2\2\25\u0085\3\2\2\2\27\u008c\3\2\2\2") - buf.write("\31\u008e\3\2\2\2\33\u0090\3\2\2\2\35\u0092\3\2\2\2\37") - buf.write("\u0094\3\2\2\2!\u0096\3\2\2\2#\u0098\3\2\2\2%\u009a\3") - buf.write("\2\2\2\'\u009d\3\2\2\2)\u00a0\3\2\2\2+\u00a2\3\2\2\2-") - buf.write("\u00a4\3\2\2\2/\u00a6\3\2\2\2\61\u00aa\3\2\2\2\63\u00af") - buf.write("\3\2\2\2\65\u00b4\3\2\2\2\67\u00ba\3\2\2\29\u00be\3\2") - buf.write("\2\2;\u00c2\3\2\2\2=\u00c6\3\2\2\2?\u00cb\3\2\2\2A\u00d0") - buf.write("\3\2\2\2C\u00d3\3\2\2\2E\u00d6\3\2\2\2G\u00d9\3\2\2\2") - buf.write("I\u00db\3\2\2\2K\u00dd\3\2\2\2M\u00e0\3\2\2\2O\u00e3\3") - buf.write("\2\2\2Q\u00f4\3\2\2\2S\u00f6\3\2\2\2U\u0100\3\2\2\2W\u0102") - buf.write("\3\2\2\2Y\u0104\3\2\2\2[\u010c\3\2\2\2]\u0110\3\2\2\2") - buf.write("_\u0112\3\2\2\2a\u0114\3\2\2\2c\u0116\3\2\2\2e\u011d\3") - buf.write("\2\2\2g\u0128\3\2\2\2i\u012e\3\2\2\2k\u013c\3\2\2\2mn") - buf.write("\7*\2\2n\4\3\2\2\2op\7+\2\2p\6\3\2\2\2qr\7}\2\2r\b\3\2") - buf.write("\2\2st\7\177\2\2t\n\3\2\2\2uv\7.\2\2v\f\3\2\2\2wx\7=\2") - buf.write("\2x\16\3\2\2\2yz\7h\2\2z{\7q\2\2{|\7t\2\2|\20\3\2\2\2") - buf.write("}~\7k\2\2~\177\7h\2\2\177\22\3\2\2\2\u0080\u0081\7g\2") - buf.write("\2\u0081\u0082\7n\2\2\u0082\u0083\7u\2\2\u0083\u0084\7") - buf.write("g\2\2\u0084\24\3\2\2\2\u0085\u0086\7t\2\2\u0086\u0087") - buf.write("\7g\2\2\u0087\u0088\7v\2\2\u0088\u0089\7w\2\2\u0089\u008a") - buf.write("\7t\2\2\u008a\u008b\7p\2\2\u008b\26\3\2\2\2\u008c\u008d") - buf.write("\7?\2\2\u008d\30\3\2\2\2\u008e\u008f\7]\2\2\u008f\32\3") - buf.write("\2\2\2\u0090\u0091\7_\2\2\u0091\34\3\2\2\2\u0092\u0093") - buf.write("\7,\2\2\u0093\36\3\2\2\2\u0094\u0095\7\61\2\2\u0095 \3") - buf.write("\2\2\2\u0096\u0097\7-\2\2\u0097\"\3\2\2\2\u0098\u0099") - buf.write("\7/\2\2\u0099$\3\2\2\2\u009a\u009b\7>\2\2\u009b\u009c") - buf.write("\7>\2\2\u009c&\3\2\2\2\u009d\u009e\7@\2\2\u009e\u009f") - buf.write("\7@\2\2\u009f(\3\2\2\2\u00a0\u00a1\7(\2\2\u00a1*\3\2\2") - buf.write("\2\u00a2\u00a3\7~\2\2\u00a3,\3\2\2\2\u00a4\u00a5\7`\2") - buf.write("\2\u00a5.\3\2\2\2\u00a6\u00a7\7k\2\2\u00a7\u00a8\7p\2") - buf.write("\2\u00a8\u00a9\7v\2\2\u00a9\60\3\2\2\2\u00aa\u00ab\7w") - buf.write("\2\2\u00ab\u00ac\7k\2\2\u00ac\u00ad\7p\2\2\u00ad\u00ae") - buf.write("\7v\2\2\u00ae\62\3\2\2\2\u00af\u00b0\7u\2\2\u00b0\u00b1") - buf.write("\7k\2\2\u00b1\u00b2\7p\2\2\u00b2\u00b3\7v\2\2\u00b3\64") - buf.write("\3\2\2\2\u00b4\u00b5\7u\2\2\u00b5\u00b6\7w\2\2\u00b6\u00b7") - buf.write("\7k\2\2\u00b7\u00b8\7p\2\2\u00b8\u00b9\7v\2\2\u00b9\66") - buf.write("\3\2\2\2\u00ba\u00bb\7h\2\2\u00bb\u00bc\7n\2\2\u00bc\u00bd") - buf.write("\7v\2\2\u00bd8\3\2\2\2\u00be\u00bf\7e\2\2\u00bf\u00c0") - buf.write("\7r\2\2\u00c0\u00c1\7n\2\2\u00c1:\3\2\2\2\u00c2\u00c3") - buf.write("\7r\2\2\u00c3\u00c4\7k\2\2\u00c4\u00c5\7z\2\2\u00c5<\3") - buf.write("\2\2\2\u00c6\u00c7\7k\2\2\u00c7\u00c8\7r\2\2\u00c8\u00c9") - buf.write("\7x\2\2\u00c9\u00ca\7\66\2\2\u00ca>\3\2\2\2\u00cb\u00cc") - buf.write("\7k\2\2\u00cc\u00cd\7r\2\2\u00cd\u00ce\7x\2\2\u00ce\u00cf") - buf.write("\78\2\2\u00cf@\3\2\2\2\u00d0\u00d1\7]\2\2\u00d1\u00d2") - buf.write("\7_\2\2\u00d2B\3\2\2\2\u00d3\u00d4\7?\2\2\u00d4\u00d5") - buf.write("\7?\2\2\u00d5D\3\2\2\2\u00d6\u00d7\7#\2\2\u00d7\u00d8") - buf.write("\7?\2\2\u00d8F\3\2\2\2\u00d9\u00da\7>\2\2\u00daH\3\2\2") - buf.write("\2\u00db\u00dc\7@\2\2\u00dcJ\3\2\2\2\u00dd\u00de\7>\2") - buf.write("\2\u00de\u00df\7?\2\2\u00dfL\3\2\2\2\u00e0\u00e1\7@\2") - buf.write("\2\u00e1\u00e2\7?\2\2\u00e2N\3\2\2\2\u00e3\u00e5\5U+\2") - buf.write("\u00e4\u00e6\5Q)\2\u00e5\u00e4\3\2\2\2\u00e5\u00e6\3\2") - buf.write("\2\2\u00e6\u00e8\3\2\2\2\u00e7\u00e9\5S*\2\u00e8\u00e7") - buf.write("\3\2\2\2\u00e8\u00e9\3\2\2\2\u00e9P\3\2\2\2\u00ea\u00ec") - buf.write("\7g\2\2\u00eb\u00ed\5a\61\2\u00ec\u00eb\3\2\2\2\u00ec") - buf.write("\u00ed\3\2\2\2\u00ed\u00ee\3\2\2\2\u00ee\u00f5\5[.\2\u00ef") - buf.write("\u00f1\7G\2\2\u00f0\u00f2\5a\61\2\u00f1\u00f0\3\2\2\2") - buf.write("\u00f1\u00f2\3\2\2\2\u00f2\u00f3\3\2\2\2\u00f3\u00f5\5") - buf.write("[.\2\u00f4\u00ea\3\2\2\2\u00f4\u00ef\3\2\2\2\u00f5R\3") - buf.write("\2\2\2\u00f6\u00f7\t\2\2\2\u00f7T\3\2\2\2\u00f8\u00fa") - buf.write("\5[.\2\u00f9\u00f8\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fb") - buf.write("\3\2\2\2\u00fb\u00fc\7\60\2\2\u00fc\u0101\5[.\2\u00fd") - buf.write("\u00fe\5[.\2\u00fe\u00ff\7\60\2\2\u00ff\u0101\3\2\2\2") - buf.write("\u0100\u00f9\3\2\2\2\u0100\u00fd\3\2\2\2\u0101V\3\2\2") - buf.write("\2\u0102\u0103\5[.\2\u0103X\3\2\2\2\u0104\u0108\5_\60") - buf.write("\2\u0105\u0107\5]/\2\u0106\u0105\3\2\2\2\u0107\u010a\3") - buf.write("\2\2\2\u0108\u0106\3\2\2\2\u0108\u0109\3\2\2\2\u0109Z") - buf.write("\3\2\2\2\u010a\u0108\3\2\2\2\u010b\u010d\5]/\2\u010c\u010b") - buf.write("\3\2\2\2\u010d\u010e\3\2\2\2\u010e\u010c\3\2\2\2\u010e") - buf.write("\u010f\3\2\2\2\u010f\\\3\2\2\2\u0110\u0111\t\3\2\2\u0111") - buf.write("^\3\2\2\2\u0112\u0113\t\4\2\2\u0113`\3\2\2\2\u0114\u0115") - buf.write("\t\5\2\2\u0115b\3\2\2\2\u0116\u011a\t\6\2\2\u0117\u0119") - buf.write("\t\7\2\2\u0118\u0117\3\2\2\2\u0119\u011c\3\2\2\2\u011a") - buf.write("\u0118\3\2\2\2\u011a\u011b\3\2\2\2\u011bd\3\2\2\2\u011c") - buf.write("\u011a\3\2\2\2\u011d\u011e\7%\2\2\u011e\u011f\7*\2\2\u011f") - buf.write("\u0121\3\2\2\2\u0120\u0122\n\b\2\2\u0121\u0120\3\2\2\2") - buf.write("\u0122\u0123\3\2\2\2\u0123\u0121\3\2\2\2\u0123\u0124\3") - buf.write("\2\2\2\u0124\u0125\3\2\2\2\u0125\u0126\7+\2\2\u0126f\3") - buf.write("\2\2\2\u0127\u0129\t\t\2\2\u0128\u0127\3\2\2\2\u0129\u012a") - buf.write("\3\2\2\2\u012a\u0128\3\2\2\2\u012a\u012b\3\2\2\2\u012b") - buf.write("\u012c\3\2\2\2\u012c\u012d\b\64\2\2\u012dh\3\2\2\2\u012e") - buf.write("\u012f\7\61\2\2\u012f\u0130\7\61\2\2\u0130\u0134\3\2\2") - buf.write("\2\u0131\u0133\13\2\2\2\u0132\u0131\3\2\2\2\u0133\u0136") - buf.write("\3\2\2\2\u0134\u0135\3\2\2\2\u0134\u0132\3\2\2\2\u0135") - buf.write("\u0137\3\2\2\2\u0136\u0134\3\2\2\2\u0137\u0138\5k\66\2") - buf.write("\u0138\u0139\3\2\2\2\u0139\u013a\b\65\2\2\u013aj\3\2\2") - buf.write("\2\u013b\u013d\7\17\2\2\u013c\u013b\3\2\2\2\u013c\u013d") - buf.write("\3\2\2\2\u013d\u013e\3\2\2\2\u013e\u013f\7\f\2\2\u013f") - buf.write("\u0140\3\2\2\2\u0140\u0141\b\66\2\2\u0141l\3\2\2\2\21") - buf.write("\2\u00e5\u00e8\u00ec\u00f1\u00f4\u00f9\u0100\u0108\u010e") - buf.write("\u011a\u0123\u012a\u0134\u013c\3\b\2\2") - return buf.getvalue() - - -class HybroLangLexer(Lexer): - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - - T__0 = 1 - T__1 = 2 - T__2 = 3 - T__3 = 4 - T__4 = 5 - T__5 = 6 - T__6 = 7 - T__7 = 8 - T__8 = 9 - T__9 = 10 - T__10 = 11 - T__11 = 12 - T__12 = 13 - T__13 = 14 - T__14 = 15 - T__15 = 16 - T__16 = 17 - T__17 = 18 - T__18 = 19 - T__19 = 20 - T__20 = 21 - T__21 = 22 - T__22 = 23 - T__23 = 24 - T__24 = 25 - T__25 = 26 - T__26 = 27 - T__27 = 28 - T__28 = 29 - T__29 = 30 - T__30 = 31 - T__31 = 32 - T__32 = 33 - T__33 = 34 - T__34 = 35 - T__35 = 36 - T__36 = 37 - T__37 = 38 - DecimalFloatingConstant = 39 - IntegerConstant = 40 - DecimalConstant = 41 - Name = 42 - INLINE = 43 - WhiteSpace = 44 - LineComment = 45 - NewLine = 46 - - channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] - - modeNames = [ "DEFAULT_MODE" ] - - literalNames = [ "", - "'('", "')'", "'{'", "'}'", "','", "';'", "'for'", "'if'", "'else'", - "'return'", "'='", "'['", "']'", "'*'", "'/'", "'+'", "'-'", - "'<<'", "'>>'", "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", - "'suint'", "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", - "'=='", "'!='", "'<'", "'>'", "'<='", "'>='" ] - - symbolicNames = [ "", - "DecimalFloatingConstant", "IntegerConstant", "DecimalConstant", - "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" ] - - ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", - "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13", - "T__14", "T__15", "T__16", "T__17", "T__18", "T__19", - "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", - "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", - "T__32", "T__33", "T__34", "T__35", "T__36", "T__37", - "DecimalFloatingConstant", "ExponentPart", "FloatingSuffix", - "FractionalConstant", "IntegerConstant", "DecimalConstant", - "DigitSequence", "Digit", "NonzeroDigit", "Sign", "Name", - "INLINE", "WhiteSpace", "LineComment", "NewLine" ] - - grammarFileName = "HybroLang.g4" - - def __init__(self, input=None, output:TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.9.2") - self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) - self._actions = None - self._predicates = None - - diff --git a/HybroLang/HybroLangLexer.tokens b/HybroLang/HybroLangLexer.tokens deleted file mode 100644 index 574a34a..0000000 --- a/HybroLang/HybroLangLexer.tokens +++ /dev/null @@ -1,84 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -T__4=5 -T__5=6 -T__6=7 -T__7=8 -T__8=9 -T__9=10 -T__10=11 -T__11=12 -T__12=13 -T__13=14 -T__14=15 -T__15=16 -T__16=17 -T__17=18 -T__18=19 -T__19=20 -T__20=21 -T__21=22 -T__22=23 -T__23=24 -T__24=25 -T__25=26 -T__26=27 -T__27=28 -T__28=29 -T__29=30 -T__30=31 -T__31=32 -T__32=33 -T__33=34 -T__34=35 -T__35=36 -T__36=37 -T__37=38 -DecimalFloatingConstant=39 -IntegerConstant=40 -DecimalConstant=41 -Name=42 -INLINE=43 -WhiteSpace=44 -LineComment=45 -NewLine=46 -'('=1 -')'=2 -'{'=3 -'}'=4 -','=5 -';'=6 -'for'=7 -'if'=8 -'else'=9 -'return'=10 -'='=11 -'['=12 -']'=13 -'*'=14 -'/'=15 -'+'=16 -'-'=17 -'<<'=18 -'>>'=19 -'&'=20 -'|'=21 -'^'=22 -'int'=23 -'uint'=24 -'sint'=25 -'suint'=26 -'flt'=27 -'cpl'=28 -'pix'=29 -'ipv4'=30 -'ipv6'=31 -'[]'=32 -'=='=33 -'!='=34 -'<'=35 -'>'=36 -'<='=37 -'>='=38 diff --git a/HybroLang/HybroLangParser.py b/HybroLang/HybroLangParser.py deleted file mode 100644 index 9a40ce4..0000000 --- a/HybroLang/HybroLangParser.py +++ /dev/null @@ -1,1602 +0,0 @@ -# Generated from HybroLang.g4 by ANTLR 4.9.2 -# encoding: utf-8 -from antlr4 import * -from io import StringIO -import sys -if sys.version_info[1] > 5: - from typing import TextIO -else: - from typing.io import TextIO - -def serializedATN(): - with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\60") - buf.write("\u00ce\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") - buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") - buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") - buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\3\2\6\2\60\n") - buf.write("\2\r\2\16\2\61\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\5\3\5\3\5") - buf.write("\3\5\3\6\3\6\7\6A\n\6\f\6\16\6D\13\6\3\6\3\6\5\6H\n\6") - buf.write("\3\6\3\6\3\7\3\7\3\7\7\7O\n\7\f\7\16\7R\13\7\3\7\5\7U") - buf.write("\n\7\3\b\3\b\3\b\3\t\3\t\3\t\7\t]\n\t\f\t\16\t`\13\t\3") - buf.write("\n\3\n\3\n\3\13\7\13f\n\13\f\13\16\13i\13\13\3\f\3\f\3") - buf.write("\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r") - buf.write("\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3") - buf.write("\r\3\r\5\r\u008a\n\r\3\16\3\16\3\16\3\16\3\17\3\17\3\17") - buf.write("\3\17\3\17\3\17\3\17\3\17\3\17\3\17\5\17\u009a\n\17\3") - buf.write("\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20") - buf.write("\3\20\3\20\3\20\3\20\7\20\u00ab\n\20\f\20\16\20\u00ae") - buf.write("\13\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\5\21\u00b7\n") - buf.write("\21\3\22\3\22\3\22\3\22\3\23\3\23\5\23\u00bf\n\23\3\24") - buf.write("\3\24\3\24\5\24\u00c4\n\24\3\25\3\25\3\26\3\26\5\26\u00ca") - buf.write("\n\26\3\27\3\27\3\27\2\3\36\30\2\4\6\b\n\f\16\20\22\24") - buf.write("\26\30\32\34\36 \"$&(*,\2\b\3\2\20\21\3\2\22\23\3\2\24") - buf.write("\25\3\2\26\30\3\2\31!\3\2#(\2\u00cb\2/\3\2\2\2\4\63\3") - buf.write("\2\2\2\6\66\3\2\2\2\b:\3\2\2\2\n>\3\2\2\2\fT\3\2\2\2\16") - buf.write("V\3\2\2\2\20Y\3\2\2\2\22a\3\2\2\2\24g\3\2\2\2\26j\3\2") - buf.write("\2\2\30\u0089\3\2\2\2\32\u008b\3\2\2\2\34\u0099\3\2\2") - buf.write("\2\36\u009b\3\2\2\2 \u00b6\3\2\2\2\"\u00b8\3\2\2\2$\u00be") - buf.write("\3\2\2\2&\u00c3\3\2\2\2(\u00c5\3\2\2\2*\u00c7\3\2\2\2") - buf.write(",\u00cb\3\2\2\2.\60\5\4\3\2/.\3\2\2\2\60\61\3\2\2\2\61") - buf.write("/\3\2\2\2\61\62\3\2\2\2\62\3\3\2\2\2\63\64\5\6\4\2\64") - buf.write("\65\5\n\6\2\65\5\3\2\2\2\66\67\5\"\22\2\678\7,\2\289\5") - buf.write("\b\5\29\7\3\2\2\2:;\7\3\2\2;<\5\f\7\2<=\7\4\2\2=\t\3\2") - buf.write("\2\2>B\7\5\2\2?A\5\16\b\2@?\3\2\2\2AD\3\2\2\2B@\3\2\2") - buf.write("\2BC\3\2\2\2CE\3\2\2\2DB\3\2\2\2EG\5\24\13\2FH\5\32\16") - buf.write("\2GF\3\2\2\2GH\3\2\2\2HI\3\2\2\2IJ\7\6\2\2J\13\3\2\2\2") - buf.write("KP\5\22\n\2LM\7\7\2\2MO\5\22\n\2NL\3\2\2\2OR\3\2\2\2P") - buf.write("N\3\2\2\2PQ\3\2\2\2QU\3\2\2\2RP\3\2\2\2SU\3\2\2\2TK\3") - buf.write("\2\2\2TS\3\2\2\2U\r\3\2\2\2VW\5\20\t\2WX\7\b\2\2X\17\3") - buf.write("\2\2\2Y^\5\22\n\2Z[\7\7\2\2[]\7,\2\2\\Z\3\2\2\2]`\3\2") - buf.write("\2\2^\\\3\2\2\2^_\3\2\2\2_\21\3\2\2\2`^\3\2\2\2ab\5\"") - buf.write("\22\2bc\7,\2\2c\23\3\2\2\2df\5\30\r\2ed\3\2\2\2fi\3\2") - buf.write("\2\2ge\3\2\2\2gh\3\2\2\2h\25\3\2\2\2ig\3\2\2\2jk\5 \21") - buf.write("\2kl\5,\27\2lm\5 \21\2m\27\3\2\2\2no\5\34\17\2op\7\b\2") - buf.write("\2p\u008a\3\2\2\2qr\7\t\2\2rs\7\3\2\2st\5\34\17\2tu\7") - buf.write("\b\2\2uv\5\26\f\2vw\7\b\2\2wx\5\34\17\2xy\7\4\2\2yz\7") - buf.write("\5\2\2z{\5\24\13\2{|\7\6\2\2|\u008a\3\2\2\2}~\7\n\2\2") - buf.write("~\177\7\3\2\2\177\u0080\5\26\f\2\u0080\u0081\7\4\2\2\u0081") - buf.write("\u0082\7\5\2\2\u0082\u0083\5\24\13\2\u0083\u0084\7\6\2") - buf.write("\2\u0084\u0085\7\13\2\2\u0085\u0086\7\5\2\2\u0086\u0087") - buf.write("\5\24\13\2\u0087\u0088\7\6\2\2\u0088\u008a\3\2\2\2\u0089") - buf.write("n\3\2\2\2\u0089q\3\2\2\2\u0089}\3\2\2\2\u008a\31\3\2\2") - buf.write("\2\u008b\u008c\7\f\2\2\u008c\u008d\5\36\20\2\u008d\u008e") - buf.write("\7\b\2\2\u008e\33\3\2\2\2\u008f\u0090\7,\2\2\u0090\u0091") - buf.write("\7\r\2\2\u0091\u009a\5\36\20\2\u0092\u0093\7,\2\2\u0093") - buf.write("\u0094\7\16\2\2\u0094\u0095\5\36\20\2\u0095\u0096\7\17") - buf.write("\2\2\u0096\u0097\7\r\2\2\u0097\u0098\5\36\20\2\u0098\u009a") - buf.write("\3\2\2\2\u0099\u008f\3\2\2\2\u0099\u0092\3\2\2\2\u009a") - buf.write("\35\3\2\2\2\u009b\u009c\b\20\1\2\u009c\u009d\5 \21\2\u009d") - buf.write("\u00ac\3\2\2\2\u009e\u009f\f\7\2\2\u009f\u00a0\t\2\2\2") - buf.write("\u00a0\u00ab\5\36\20\b\u00a1\u00a2\f\6\2\2\u00a2\u00a3") - buf.write("\t\3\2\2\u00a3\u00ab\5\36\20\7\u00a4\u00a5\f\5\2\2\u00a5") - buf.write("\u00a6\t\4\2\2\u00a6\u00ab\5\36\20\6\u00a7\u00a8\f\4\2") - buf.write("\2\u00a8\u00a9\t\5\2\2\u00a9\u00ab\5\36\20\5\u00aa\u009e") - buf.write("\3\2\2\2\u00aa\u00a1\3\2\2\2\u00aa\u00a4\3\2\2\2\u00aa") - buf.write("\u00a7\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3\2\2\2") - buf.write("\u00ac\u00ad\3\2\2\2\u00ad\37\3\2\2\2\u00ae\u00ac\3\2") - buf.write("\2\2\u00af\u00b0\7,\2\2\u00b0\u00b1\7\16\2\2\u00b1\u00b2") - buf.write("\5\36\20\2\u00b2\u00b3\7\17\2\2\u00b3\u00b7\3\2\2\2\u00b4") - buf.write("\u00b7\5&\24\2\u00b5\u00b7\7,\2\2\u00b6\u00af\3\2\2\2") - buf.write("\u00b6\u00b4\3\2\2\2\u00b6\u00b5\3\2\2\2\u00b7!\3\2\2") - buf.write("\2\u00b8\u00b9\5*\26\2\u00b9\u00ba\5$\23\2\u00ba\u00bb") - buf.write("\5$\23\2\u00bb#\3\2\2\2\u00bc\u00bf\7*\2\2\u00bd\u00bf") - buf.write("\5(\25\2\u00be\u00bc\3\2\2\2\u00be\u00bd\3\2\2\2\u00bf") - buf.write("%\3\2\2\2\u00c0\u00c4\7*\2\2\u00c1\u00c4\7)\2\2\u00c2") - buf.write("\u00c4\5(\25\2\u00c3\u00c0\3\2\2\2\u00c3\u00c1\3\2\2\2") - buf.write("\u00c3\u00c2\3\2\2\2\u00c4\'\3\2\2\2\u00c5\u00c6\7-\2") - buf.write("\2\u00c6)\3\2\2\2\u00c7\u00c9\t\6\2\2\u00c8\u00ca\7\"") - buf.write("\2\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca+\3") - buf.write("\2\2\2\u00cb\u00cc\t\7\2\2\u00cc-\3\2\2\2\21\61BGPT^g") - buf.write("\u0089\u0099\u00aa\u00ac\u00b6\u00be\u00c3\u00c9") - return buf.getvalue() - - -class HybroLangParser ( Parser ): - - grammarFileName = "HybroLang.g4" - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - - sharedContextCache = PredictionContextCache() - - literalNames = [ "", "'('", "')'", "'{'", "'}'", "','", "';'", - "'for'", "'if'", "'else'", "'return'", "'='", "'['", - "']'", "'*'", "'/'", "'+'", "'-'", "'<<'", "'>>'", - "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", "'suint'", - "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", - "'=='", "'!='", "'<'", "'>'", "'<='", "'>='" ] - - symbolicNames = [ "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "", - "", "", "", "DecimalFloatingConstant", - "IntegerConstant", "DecimalConstant", "Name", "INLINE", - "WhiteSpace", "LineComment", "NewLine" ] - - RULE_compilationunit = 0 - RULE_function = 1 - RULE_fndcl = 2 - RULE_fnprototype = 3 - RULE_fnbody = 4 - RULE_paramdcllist = 5 - RULE_localvardef = 6 - RULE_vardcllist = 7 - RULE_vardcl = 8 - RULE_actionlist = 9 - RULE_condexpr = 10 - RULE_action = 11 - RULE_returnexpr = 12 - RULE_affectexpr = 13 - RULE_unaryexpr = 14 - RULE_varorvalue = 15 - RULE_datatype = 16 - RULE_intconstvalue = 17 - RULE_constvalue = 18 - RULE_constinline = 19 - RULE_typebase = 20 - RULE_condOperator = 21 - - ruleNames = [ "compilationunit", "function", "fndcl", "fnprototype", - "fnbody", "paramdcllist", "localvardef", "vardcllist", - "vardcl", "actionlist", "condexpr", "action", "returnexpr", - "affectexpr", "unaryexpr", "varorvalue", "datatype", - "intconstvalue", "constvalue", "constinline", "typebase", - "condOperator" ] - - EOF = Token.EOF - T__0=1 - T__1=2 - T__2=3 - T__3=4 - T__4=5 - T__5=6 - T__6=7 - T__7=8 - T__8=9 - T__9=10 - T__10=11 - T__11=12 - T__12=13 - T__13=14 - T__14=15 - T__15=16 - T__16=17 - T__17=18 - T__18=19 - T__19=20 - T__20=21 - T__21=22 - T__22=23 - T__23=24 - T__24=25 - T__25=26 - T__26=27 - T__27=28 - T__28=29 - T__29=30 - T__30=31 - T__31=32 - T__32=33 - T__33=34 - T__34=35 - T__35=36 - T__36=37 - T__37=38 - DecimalFloatingConstant=39 - IntegerConstant=40 - DecimalConstant=41 - Name=42 - INLINE=43 - WhiteSpace=44 - LineComment=45 - NewLine=46 - - def __init__(self, input:TokenStream, output:TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.9.2") - self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) - self._predicates = None - - - - class CompilationunitContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def function(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.FunctionContext) - else: - return self.getTypedRuleContext(HybroLangParser.FunctionContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_compilationunit - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitCompilationunit" ): - return visitor.visitCompilationunit(self) - else: - return visitor.visitChildren(self) - - - - - def compilationunit(self): - - localctx = HybroLangParser.CompilationunitContext(self, self._ctx, self.state) - self.enterRule(localctx, 0, self.RULE_compilationunit) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 45 - self._errHandler.sync(self) - _la = self._input.LA(1) - while True: - self.state = 44 - self.function() - self.state = 47 - self._errHandler.sync(self) - _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__22) | (1 << HybroLangParser.T__23) | (1 << HybroLangParser.T__24) | (1 << HybroLangParser.T__25) | (1 << HybroLangParser.T__26) | (1 << HybroLangParser.T__27) | (1 << HybroLangParser.T__28) | (1 << HybroLangParser.T__29) | (1 << HybroLangParser.T__30))) != 0)): - break - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class FunctionContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def fndcl(self): - return self.getTypedRuleContext(HybroLangParser.FndclContext,0) - - - def fnbody(self): - return self.getTypedRuleContext(HybroLangParser.FnbodyContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_function - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFunction" ): - return visitor.visitFunction(self) - else: - return visitor.visitChildren(self) - - - - - def function(self): - - localctx = HybroLangParser.FunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 2, self.RULE_function) - try: - self.enterOuterAlt(localctx, 1) - self.state = 49 - self.fndcl() - self.state = 50 - self.fnbody() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class FndclContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def datatype(self): - return self.getTypedRuleContext(HybroLangParser.DatatypeContext,0) - - - def Name(self): - return self.getToken(HybroLangParser.Name, 0) - - def fnprototype(self): - return self.getTypedRuleContext(HybroLangParser.FnprototypeContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_fndcl - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFndcl" ): - return visitor.visitFndcl(self) - else: - return visitor.visitChildren(self) - - - - - def fndcl(self): - - localctx = HybroLangParser.FndclContext(self, self._ctx, self.state) - self.enterRule(localctx, 4, self.RULE_fndcl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 52 - self.datatype() - self.state = 53 - self.match(HybroLangParser.Name) - self.state = 54 - self.fnprototype() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class FnprototypeContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def paramdcllist(self): - return self.getTypedRuleContext(HybroLangParser.ParamdcllistContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_fnprototype - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFnprototype" ): - return visitor.visitFnprototype(self) - else: - return visitor.visitChildren(self) - - - - - def fnprototype(self): - - localctx = HybroLangParser.FnprototypeContext(self, self._ctx, self.state) - self.enterRule(localctx, 6, self.RULE_fnprototype) - try: - self.enterOuterAlt(localctx, 1) - self.state = 56 - self.match(HybroLangParser.T__0) - self.state = 57 - self.paramdcllist() - self.state = 58 - self.match(HybroLangParser.T__1) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class FnbodyContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def actionlist(self): - return self.getTypedRuleContext(HybroLangParser.ActionlistContext,0) - - - def localvardef(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.LocalvardefContext) - else: - return self.getTypedRuleContext(HybroLangParser.LocalvardefContext,i) - - - def returnexpr(self): - return self.getTypedRuleContext(HybroLangParser.ReturnexprContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_fnbody - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFnbody" ): - return visitor.visitFnbody(self) - else: - return visitor.visitChildren(self) - - - - - def fnbody(self): - - localctx = HybroLangParser.FnbodyContext(self, self._ctx, self.state) - self.enterRule(localctx, 8, self.RULE_fnbody) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 60 - self.match(HybroLangParser.T__2) - self.state = 64 - self._errHandler.sync(self) - _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__22) | (1 << HybroLangParser.T__23) | (1 << HybroLangParser.T__24) | (1 << HybroLangParser.T__25) | (1 << HybroLangParser.T__26) | (1 << HybroLangParser.T__27) | (1 << HybroLangParser.T__28) | (1 << HybroLangParser.T__29) | (1 << HybroLangParser.T__30))) != 0): - self.state = 61 - self.localvardef() - self.state = 66 - self._errHandler.sync(self) - _la = self._input.LA(1) - - self.state = 67 - self.actionlist() - self.state = 69 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==HybroLangParser.T__9: - self.state = 68 - self.returnexpr() - - - self.state = 71 - self.match(HybroLangParser.T__3) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ParamdcllistContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def vardcl(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.VardclContext) - else: - return self.getTypedRuleContext(HybroLangParser.VardclContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_paramdcllist - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitParamdcllist" ): - return visitor.visitParamdcllist(self) - else: - return visitor.visitChildren(self) - - - - - def paramdcllist(self): - - localctx = HybroLangParser.ParamdcllistContext(self, self._ctx, self.state) - self.enterRule(localctx, 10, self.RULE_paramdcllist) - self._la = 0 # Token type - try: - self.state = 82 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [HybroLangParser.T__22, HybroLangParser.T__23, HybroLangParser.T__24, HybroLangParser.T__25, HybroLangParser.T__26, HybroLangParser.T__27, HybroLangParser.T__28, HybroLangParser.T__29, HybroLangParser.T__30]: - self.enterOuterAlt(localctx, 1) - self.state = 73 - self.vardcl() - self.state = 78 - self._errHandler.sync(self) - _la = self._input.LA(1) - while _la==HybroLangParser.T__4: - self.state = 74 - self.match(HybroLangParser.T__4) - self.state = 75 - self.vardcl() - self.state = 80 - self._errHandler.sync(self) - _la = self._input.LA(1) - - pass - elif token in [HybroLangParser.T__1]: - self.enterOuterAlt(localctx, 2) - - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class LocalvardefContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def vardcllist(self): - return self.getTypedRuleContext(HybroLangParser.VardcllistContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_localvardef - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLocalvardef" ): - return visitor.visitLocalvardef(self) - else: - return visitor.visitChildren(self) - - - - - def localvardef(self): - - localctx = HybroLangParser.LocalvardefContext(self, self._ctx, self.state) - self.enterRule(localctx, 12, self.RULE_localvardef) - try: - self.enterOuterAlt(localctx, 1) - self.state = 84 - self.vardcllist() - self.state = 85 - self.match(HybroLangParser.T__5) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class VardcllistContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def vardcl(self): - return self.getTypedRuleContext(HybroLangParser.VardclContext,0) - - - def Name(self, i:int=None): - if i is None: - return self.getTokens(HybroLangParser.Name) - else: - return self.getToken(HybroLangParser.Name, i) - - def getRuleIndex(self): - return HybroLangParser.RULE_vardcllist - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitVardcllist" ): - return visitor.visitVardcllist(self) - else: - return visitor.visitChildren(self) - - - - - def vardcllist(self): - - localctx = HybroLangParser.VardcllistContext(self, self._ctx, self.state) - self.enterRule(localctx, 14, self.RULE_vardcllist) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 87 - self.vardcl() - self.state = 92 - self._errHandler.sync(self) - _la = self._input.LA(1) - while _la==HybroLangParser.T__4: - self.state = 88 - self.match(HybroLangParser.T__4) - self.state = 89 - self.match(HybroLangParser.Name) - self.state = 94 - self._errHandler.sync(self) - _la = self._input.LA(1) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class VardclContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def datatype(self): - return self.getTypedRuleContext(HybroLangParser.DatatypeContext,0) - - - def Name(self): - return self.getToken(HybroLangParser.Name, 0) - - def getRuleIndex(self): - return HybroLangParser.RULE_vardcl - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitVardcl" ): - return visitor.visitVardcl(self) - else: - return visitor.visitChildren(self) - - - - - def vardcl(self): - - localctx = HybroLangParser.VardclContext(self, self._ctx, self.state) - self.enterRule(localctx, 16, self.RULE_vardcl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 95 - self.datatype() - self.state = 96 - self.match(HybroLangParser.Name) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ActionlistContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def action(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.ActionContext) - else: - return self.getTypedRuleContext(HybroLangParser.ActionContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_actionlist - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitActionlist" ): - return visitor.visitActionlist(self) - else: - return visitor.visitChildren(self) - - - - - def actionlist(self): - - localctx = HybroLangParser.ActionlistContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_actionlist) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 101 - self._errHandler.sync(self) - _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__6) | (1 << HybroLangParser.T__7) | (1 << HybroLangParser.Name))) != 0): - self.state = 98 - self.action() - self.state = 103 - self._errHandler.sync(self) - _la = self._input.LA(1) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class CondexprContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def varorvalue(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.VarorvalueContext) - else: - return self.getTypedRuleContext(HybroLangParser.VarorvalueContext,i) - - - def condOperator(self): - return self.getTypedRuleContext(HybroLangParser.CondOperatorContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_condexpr - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitCondexpr" ): - return visitor.visitCondexpr(self) - else: - return visitor.visitChildren(self) - - - - - def condexpr(self): - - localctx = HybroLangParser.CondexprContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_condexpr) - try: - self.enterOuterAlt(localctx, 1) - self.state = 104 - self.varorvalue() - self.state = 105 - self.condOperator() - self.state = 106 - self.varorvalue() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ActionContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def affectexpr(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.AffectexprContext) - else: - return self.getTypedRuleContext(HybroLangParser.AffectexprContext,i) - - - def condexpr(self): - return self.getTypedRuleContext(HybroLangParser.CondexprContext,0) - - - def actionlist(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.ActionlistContext) - else: - return self.getTypedRuleContext(HybroLangParser.ActionlistContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_action - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAction" ): - return visitor.visitAction(self) - else: - return visitor.visitChildren(self) - - - - - def action(self): - - localctx = HybroLangParser.ActionContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_action) - try: - self.state = 135 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [HybroLangParser.Name]: - self.enterOuterAlt(localctx, 1) - self.state = 108 - self.affectexpr() - self.state = 109 - self.match(HybroLangParser.T__5) - pass - elif token in [HybroLangParser.T__6]: - self.enterOuterAlt(localctx, 2) - self.state = 111 - self.match(HybroLangParser.T__6) - self.state = 112 - self.match(HybroLangParser.T__0) - self.state = 113 - self.affectexpr() - self.state = 114 - self.match(HybroLangParser.T__5) - self.state = 115 - self.condexpr() - self.state = 116 - self.match(HybroLangParser.T__5) - self.state = 117 - self.affectexpr() - self.state = 118 - self.match(HybroLangParser.T__1) - self.state = 119 - self.match(HybroLangParser.T__2) - self.state = 120 - self.actionlist() - self.state = 121 - self.match(HybroLangParser.T__3) - pass - elif token in [HybroLangParser.T__7]: - self.enterOuterAlt(localctx, 3) - self.state = 123 - self.match(HybroLangParser.T__7) - self.state = 124 - self.match(HybroLangParser.T__0) - self.state = 125 - self.condexpr() - self.state = 126 - self.match(HybroLangParser.T__1) - self.state = 127 - self.match(HybroLangParser.T__2) - self.state = 128 - self.actionlist() - self.state = 129 - self.match(HybroLangParser.T__3) - self.state = 130 - self.match(HybroLangParser.T__8) - self.state = 131 - self.match(HybroLangParser.T__2) - self.state = 132 - self.actionlist() - self.state = 133 - self.match(HybroLangParser.T__3) - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ReturnexprContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def unaryexpr(self): - return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_returnexpr - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitReturnexpr" ): - return visitor.visitReturnexpr(self) - else: - return visitor.visitChildren(self) - - - - - def returnexpr(self): - - localctx = HybroLangParser.ReturnexprContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_returnexpr) - try: - self.enterOuterAlt(localctx, 1) - self.state = 137 - self.match(HybroLangParser.T__9) - self.state = 138 - self.unaryexpr(0) - self.state = 139 - self.match(HybroLangParser.T__5) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class AffectexprContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def Name(self): - return self.getToken(HybroLangParser.Name, 0) - - def unaryexpr(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.UnaryexprContext) - else: - return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_affectexpr - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAffectexpr" ): - return visitor.visitAffectexpr(self) - else: - return visitor.visitChildren(self) - - - - - def affectexpr(self): - - localctx = HybroLangParser.AffectexprContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_affectexpr) - try: - self.state = 151 - self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,8,self._ctx) - if la_ == 1: - self.enterOuterAlt(localctx, 1) - self.state = 141 - self.match(HybroLangParser.Name) - self.state = 142 - self.match(HybroLangParser.T__10) - self.state = 143 - self.unaryexpr(0) - pass - - elif la_ == 2: - self.enterOuterAlt(localctx, 2) - self.state = 144 - self.match(HybroLangParser.Name) - self.state = 145 - self.match(HybroLangParser.T__11) - self.state = 146 - self.unaryexpr(0) - self.state = 147 - self.match(HybroLangParser.T__12) - self.state = 148 - self.match(HybroLangParser.T__10) - self.state = 149 - self.unaryexpr(0) - pass - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class UnaryexprContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - self.op = None # Token - - def varorvalue(self): - return self.getTypedRuleContext(HybroLangParser.VarorvalueContext,0) - - - def unaryexpr(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.UnaryexprContext) - else: - return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_unaryexpr - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitUnaryexpr" ): - return visitor.visitUnaryexpr(self) - else: - return visitor.visitChildren(self) - - - - def unaryexpr(self, _p:int=0): - _parentctx = self._ctx - _parentState = self.state - localctx = HybroLangParser.UnaryexprContext(self, self._ctx, _parentState) - _prevctx = localctx - _startState = 28 - self.enterRecursionRule(localctx, 28, self.RULE_unaryexpr, _p) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 154 - self.varorvalue() - self._ctx.stop = self._input.LT(-1) - self.state = 170 - self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,10,self._ctx) - while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: - if _alt==1: - if self._parseListeners is not None: - self.triggerExitRuleEvent() - _prevctx = localctx - self.state = 168 - self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,9,self._ctx) - if la_ == 1: - localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) - self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) - self.state = 156 - if not self.precpred(self._ctx, 5): - from antlr4.error.Errors import FailedPredicateException - raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") - self.state = 157 - localctx.op = self._input.LT(1) - _la = self._input.LA(1) - if not(_la==HybroLangParser.T__13 or _la==HybroLangParser.T__14): - localctx.op = self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - self.state = 158 - self.unaryexpr(6) - pass - - elif la_ == 2: - localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) - self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) - self.state = 159 - if not self.precpred(self._ctx, 4): - from antlr4.error.Errors import FailedPredicateException - raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") - self.state = 160 - localctx.op = self._input.LT(1) - _la = self._input.LA(1) - if not(_la==HybroLangParser.T__15 or _la==HybroLangParser.T__16): - localctx.op = self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - self.state = 161 - self.unaryexpr(5) - pass - - elif la_ == 3: - localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) - self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) - self.state = 162 - if not self.precpred(self._ctx, 3): - from antlr4.error.Errors import FailedPredicateException - raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") - self.state = 163 - localctx.op = self._input.LT(1) - _la = self._input.LA(1) - if not(_la==HybroLangParser.T__17 or _la==HybroLangParser.T__18): - localctx.op = self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - self.state = 164 - self.unaryexpr(4) - pass - - elif la_ == 4: - localctx = HybroLangParser.UnaryexprContext(self, _parentctx, _parentState) - self.pushNewRecursionContext(localctx, _startState, self.RULE_unaryexpr) - self.state = 165 - if not self.precpred(self._ctx, 2): - from antlr4.error.Errors import FailedPredicateException - raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 166 - localctx.op = self._input.LT(1) - _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__19) | (1 << HybroLangParser.T__20) | (1 << HybroLangParser.T__21))) != 0)): - localctx.op = self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - self.state = 167 - self.unaryexpr(3) - pass - - - self.state = 172 - self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,10,self._ctx) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.unrollRecursionContexts(_parentctx) - return localctx - - class VarorvalueContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - - def getRuleIndex(self): - return HybroLangParser.RULE_varorvalue - - - def copyFrom(self, ctx:ParserRuleContext): - super().copyFrom(ctx) - - - - class VarorvalueVarContext(VarorvalueContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a HybroLangParser.VarorvalueContext - super().__init__(parser) - self.copyFrom(ctx) - - def Name(self): - return self.getToken(HybroLangParser.Name, 0) - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitVarorvalueVar" ): - return visitor.visitVarorvalueVar(self) - else: - return visitor.visitChildren(self) - - - class VarorvalueArrayContext(VarorvalueContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a HybroLangParser.VarorvalueContext - super().__init__(parser) - self.copyFrom(ctx) - - def Name(self): - return self.getToken(HybroLangParser.Name, 0) - def unaryexpr(self): - return self.getTypedRuleContext(HybroLangParser.UnaryexprContext,0) - - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitVarorvalueArray" ): - return visitor.visitVarorvalueArray(self) - else: - return visitor.visitChildren(self) - - - class VarorvalueConstContext(VarorvalueContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a HybroLangParser.VarorvalueContext - super().__init__(parser) - self.copyFrom(ctx) - - def constvalue(self): - return self.getTypedRuleContext(HybroLangParser.ConstvalueContext,0) - - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitVarorvalueConst" ): - return visitor.visitVarorvalueConst(self) - else: - return visitor.visitChildren(self) - - - - def varorvalue(self): - - localctx = HybroLangParser.VarorvalueContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_varorvalue) - try: - self.state = 180 - self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,11,self._ctx) - if la_ == 1: - localctx = HybroLangParser.VarorvalueArrayContext(self, localctx) - self.enterOuterAlt(localctx, 1) - self.state = 173 - self.match(HybroLangParser.Name) - self.state = 174 - self.match(HybroLangParser.T__11) - self.state = 175 - self.unaryexpr(0) - self.state = 176 - self.match(HybroLangParser.T__12) - pass - - elif la_ == 2: - localctx = HybroLangParser.VarorvalueConstContext(self, localctx) - self.enterOuterAlt(localctx, 2) - self.state = 178 - self.constvalue() - pass - - elif la_ == 3: - localctx = HybroLangParser.VarorvalueVarContext(self, localctx) - self.enterOuterAlt(localctx, 3) - self.state = 179 - self.match(HybroLangParser.Name) - pass - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class DatatypeContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - self.wordlen = None # IntconstvalueContext - self.vectorlen = None # IntconstvalueContext - - def typebase(self): - return self.getTypedRuleContext(HybroLangParser.TypebaseContext,0) - - - def intconstvalue(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(HybroLangParser.IntconstvalueContext) - else: - return self.getTypedRuleContext(HybroLangParser.IntconstvalueContext,i) - - - def getRuleIndex(self): - return HybroLangParser.RULE_datatype - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitDatatype" ): - return visitor.visitDatatype(self) - else: - return visitor.visitChildren(self) - - - - - def datatype(self): - - localctx = HybroLangParser.DatatypeContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_datatype) - try: - self.enterOuterAlt(localctx, 1) - self.state = 182 - self.typebase() - self.state = 183 - localctx.wordlen = self.intconstvalue() - self.state = 184 - localctx.vectorlen = self.intconstvalue() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class IntconstvalueContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def IntegerConstant(self): - return self.getToken(HybroLangParser.IntegerConstant, 0) - - def constinline(self): - return self.getTypedRuleContext(HybroLangParser.ConstinlineContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_intconstvalue - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitIntconstvalue" ): - return visitor.visitIntconstvalue(self) - else: - return visitor.visitChildren(self) - - - - - def intconstvalue(self): - - localctx = HybroLangParser.IntconstvalueContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_intconstvalue) - try: - self.state = 188 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [HybroLangParser.IntegerConstant]: - self.enterOuterAlt(localctx, 1) - self.state = 186 - self.match(HybroLangParser.IntegerConstant) - pass - elif token in [HybroLangParser.INLINE]: - self.enterOuterAlt(localctx, 2) - self.state = 187 - self.constinline() - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ConstvalueContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def IntegerConstant(self): - return self.getToken(HybroLangParser.IntegerConstant, 0) - - def DecimalFloatingConstant(self): - return self.getToken(HybroLangParser.DecimalFloatingConstant, 0) - - def constinline(self): - return self.getTypedRuleContext(HybroLangParser.ConstinlineContext,0) - - - def getRuleIndex(self): - return HybroLangParser.RULE_constvalue - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitConstvalue" ): - return visitor.visitConstvalue(self) - else: - return visitor.visitChildren(self) - - - - - def constvalue(self): - - localctx = HybroLangParser.ConstvalueContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_constvalue) - try: - self.state = 193 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [HybroLangParser.IntegerConstant]: - self.enterOuterAlt(localctx, 1) - self.state = 190 - self.match(HybroLangParser.IntegerConstant) - pass - elif token in [HybroLangParser.DecimalFloatingConstant]: - self.enterOuterAlt(localctx, 2) - self.state = 191 - self.match(HybroLangParser.DecimalFloatingConstant) - pass - elif token in [HybroLangParser.INLINE]: - self.enterOuterAlt(localctx, 3) - self.state = 192 - self.constinline() - pass - else: - raise NoViableAltException(self) - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class ConstinlineContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - def INLINE(self): - return self.getToken(HybroLangParser.INLINE, 0) - - def getRuleIndex(self): - return HybroLangParser.RULE_constinline - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitConstinline" ): - return visitor.visitConstinline(self) - else: - return visitor.visitChildren(self) - - - - - def constinline(self): - - localctx = HybroLangParser.ConstinlineContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_constinline) - try: - self.enterOuterAlt(localctx, 1) - self.state = 195 - self.match(HybroLangParser.INLINE) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class TypebaseContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - - def getRuleIndex(self): - return HybroLangParser.RULE_typebase - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitTypebase" ): - return visitor.visitTypebase(self) - else: - return visitor.visitChildren(self) - - - - - def typebase(self): - - localctx = HybroLangParser.TypebaseContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_typebase) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 197 - _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__22) | (1 << HybroLangParser.T__23) | (1 << HybroLangParser.T__24) | (1 << HybroLangParser.T__25) | (1 << HybroLangParser.T__26) | (1 << HybroLangParser.T__27) | (1 << HybroLangParser.T__28) | (1 << HybroLangParser.T__29) | (1 << HybroLangParser.T__30))) != 0)): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - self.state = 199 - self._errHandler.sync(self) - _la = self._input.LA(1) - if _la==HybroLangParser.T__31: - self.state = 198 - self.match(HybroLangParser.T__31) - - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class CondOperatorContext(ParserRuleContext): - __slots__ = 'parser' - - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): - super().__init__(parent, invokingState) - self.parser = parser - - - def getRuleIndex(self): - return HybroLangParser.RULE_condOperator - - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitCondOperator" ): - return visitor.visitCondOperator(self) - else: - return visitor.visitChildren(self) - - - - - def condOperator(self): - - localctx = HybroLangParser.CondOperatorContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_condOperator) - self._la = 0 # Token type - try: - self.enterOuterAlt(localctx, 1) - self.state = 201 - _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HybroLangParser.T__32) | (1 << HybroLangParser.T__33) | (1 << HybroLangParser.T__34) | (1 << HybroLangParser.T__35) | (1 << HybroLangParser.T__36) | (1 << HybroLangParser.T__37))) != 0)): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - - - def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): - if self._predicates == None: - self._predicates = dict() - self._predicates[14] = self.unaryexpr_sempred - pred = self._predicates.get(ruleIndex, None) - if pred is None: - raise Exception("No predicate with index:" + str(ruleIndex)) - else: - return pred(localctx, predIndex) - - def unaryexpr_sempred(self, localctx:UnaryexprContext, predIndex:int): - if predIndex == 0: - return self.precpred(self._ctx, 5) - - - if predIndex == 1: - return self.precpred(self._ctx, 4) - - - if predIndex == 2: - return self.precpred(self._ctx, 3) - - - if predIndex == 3: - return self.precpred(self._ctx, 2) - - - - - diff --git a/HybroLang/__pycache__/H2Aarch64Rewrite.cpython-312.pyc b/HybroLang/__pycache__/H2Aarch64Rewrite.cpython-312.pyc deleted file mode 100644 index f4992e9295775b9fb3ea4eab77616b678de3dd95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 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 diff --git a/HybroLang/__pycache__/H2Debug.cpython-312.pyc b/HybroLang/__pycache__/H2Debug.cpython-312.pyc deleted file mode 100644 index cc47201e2efa06d87eb07f1845d40d366ea45b70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3339 zcmbtXO>7&-6`tkplFKD&(W0c#6lJZIGAd<9)Sn$gC|cN1U^58hMs`wEZ6U00lUM>i_&@^zqM`-NAPLF>Jy5j{${|3GMX$YRO&cT@ZV{lp_@-JY3i#5#S#n6( zHP8Z`!_1qR@6Eh<^X7ZIe+q>}1m&Brn%W-)g#Jo8v~V5acnXAvNI?pdMO(}=!w}h% z^=z@rEQ37g8dBK%NZ}rN+8WDTkxzP`lTMOxyw_(IbBYR**p_Y;^J=DzY}ZVub9@$r zhe$=sjDnUu3UePVvx*05j%={Z7r7+w_^!_^sH=tb40~b?AIPMCya9`Wtqj<+1oP0No5we6M}f5!XB=FW|iv+6?t(sbq0<4U1O-B^Z9x@d|@Jy~vTX z^-*lErE4?DJWWTHAhnP|MNcwRT9$5ZcCzYHDAtbD6Syh*} zNI3CXc~#9io|!3kBBz^%R#F{qHCrIl{xulMH&raH<*=ly zcTLGK)qK+L2-Gsix1hPQ!^x(J9Uja2y6Uj7trJ*RO%ltCV1N^p73CT^X<9dQhuhKA zI}Weu`GT4BIh>(p*Bsu|%&hA0=?^u-#KgxAqd1J_aO4OE35AY_UQVYra$9OPmyxrn z?X8*1Q*(1Osq4j6oVy0TafJ`TkW?r5C-X%|Fu?VK-~4kU!cA z4m5*tI~cEiT>trDFy08xSD2RI|IGWqyZdp)`$QP-^r{@`jnLi@=}FH{5B=JxUi?+5 zaeC|p^7yAJS6Y!+^-8r+`{?t#&CywVbha^i@o@N(9l2ClXa&Q~;D{X@smis%+V*dw z_38RYd$Ui2sUsegkG#k)lAS*lo(ZADzVAI1631XGdgVov2z6g{7zFa7EynV+GbkS5$drMgKq)K=!fba zYV{3OeYNP}TN8HQ#Gx>OB^b_7LIfFg3Fj{mrVo+j*`zE+W;=yGp)v>NbGP3^2%m<> z)_HssMcOWs*FB1-43GXzltfXRT@vZ7p|JF6DjcB;mkhcT)5BS;<)uVj_Q5`Z-W-+a zK4k&sgLJglny09|Np9!0a{K#mPFCT|emIM_?6;WB$ZHVjDn84V7*^3ir?bh zTKIzbiZ6?xIryKNmd_GktD|5PR^0?*<|GaH8P+n@SHNkdg9HJKI+t!gC-MvLBr4`4wBV%{aPX=$2 z6GHaYbU8~#ahxo|f(?!jsy47Aq!oi?#ZD5Wjmy`rnWX{B(X*b1-2KCTeT-jmF@66|vPHYxYmr{S%G;3l(205NQVDb|C&cu_?{k z((L2F>>u9!T5DasexS94&}ZTUaraW~OhtSmoOi}1exLsO&f&n1Dt$Iz8!DG zukQL=;elrOoE<(_OVlIvwS%QS?OSH=_LK1Zcj3W@;xEPOe69F2JpK0&Y!8(dj&#Fdq;oKnaVIk>X2U68Zw8BA!zjZgQ&@EGYzq#{Wd!&hm$B7#BU z@;-XOh4^<~oMrg)$KFwXri~`^i|}%-l!Z*TGHwl9Srw5|Oi hPJ=ed%mzslM=ZlI|L`Ja`p;Ox| diff --git a/HybroLang/__pycache__/H2GenGen.cpython-312.pyc b/HybroLang/__pycache__/H2GenGen.cpython-312.pyc deleted file mode 100644 index 7e40116db6aafdb96a234d2e466940d726aad96d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7504 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 diff --git a/HybroLang/__pycache__/H2LabelTable.cpython-312.pyc b/HybroLang/__pycache__/H2LabelTable.cpython-312.pyc deleted file mode 100644 index 4547d66a0d85be52550dc86b148c259276d192b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2887 zcmai0O-vg{6rTODz5XG~j}uG?WeK9NgaRQng8WpXfrhHcQbW|L1hQH@3z+za>>7f% zjzTM>E^R7EFD8d7>8Yu5>7`P8>a|iYULeA;a){JZZWJn2%BgR5yK}>QYUDn zAj~|biV|9(XFWyzk`A-j^)cmd$S7d>`j5EWIXFH*|^9)cKV{9 z6iWNjKG7d3U0OUH+B*xgSvc1ih0z#|sWArA%V>ZjNhNkwo{TB_vElTjnjDc6(}FcCq{y@oarPqn6P|(pUMG+&ilPjXfU_H> zU{v%Pp$r-A>!xXu(SxOS&j~TIxA1}}hef8~v&NP$1;53I=i`%#THs_gG82~Libxk& zO^HpZ9H?l-wjjJb+clGnE3srmj&G!&Y*Id8R`P8OCym9>$Ro9R8%#o3T-mRq8=KEsfvu# zg0dLZQc<{0E12g5kygo}3f`f`h%%RoCKDo~daW5d+z{e|CyGCjWAlne925jWCCOJ{ zz_MO>C{8dF0FibY$P&u?gX`=A{yuN|Tc1_e=NiuD`mW?g$IZU+&FYCuV@L^CN6&N(<{8)9YR+-Y$ddJ`E=fUu(!~HeLCyC4VKQs zig2=+i+0ARl7hUDjAG%Ea7$Jb1VK}PE+syfN*9YlXJ;oEg`{O-O2R^wm6HyhSgb^1 zDi0?<3?pt@NnIKQ*(*8cOji+&?|>|!XZ|BbYW2>_olSq^!=?>?bG~LgcYSjE`VA9) zH8Eo_AE?X)`^`W#QL}RN9=qcrT03r3QMEQ~22L1*z*hzh{|L?Aq^z9ONCMc|r`7`dO2nMi4It8v0)Z6dYe>Ad z`Bsx}-Q>j_C%*3VewvMeP8J?Y0BG4#11SOcwo-zAV>x;~1?ou(z`>Ys0dfzZ2S|ex zk!>AtFsb-lfm%3>438vfDLB0zJXBU_!oCRFWZ1 zAl-8+6qCh*XF*oU^LRL-0a9Pc3rj?L-J!6Sirxl`+5ixUZS`9Z-H+Jqwm!41FW1;_ zR`(m8JQrByR=Bm+_1^9JQ)d0CEv^IRwz<#-7g`@MxrQh3B=X0MBUXUJaNDFX!si7* zIsto2Qo$!l@g$y)5k4SEH|OP8Q3CgllMzW$$(N9II+dW=g1mZya8Q`hPsp-uy+tay zF^dpJYX-86p0dI&%etC&1B~mPU7ybt+znB#_FXsYs`)3tx@v8GqCwn>%h3e5;+jj| zg6|98q%sZTZfI7OE^tZ$li_LgEuwHB?|DJs6BgaJ6DNt3idk-hF*TY<+1`_w9(eqc zyI`OGJ+%u2|CJ`8!+?@rtT>hT>EsBYgih1&bq!D`eMkq tuwJ#r*5`|(b89!Z*g9uq%bv1cqiK2A>Q>uV+P~>|!q)Eah&^t3@*h*%X5s(< diff --git a/HybroLang/__pycache__/H2MovOptimize.cpython-312.pyc b/HybroLang/__pycache__/H2MovOptimize.cpython-312.pyc deleted file mode 100644 index 0dd5cc2f81115de81999a3e05d93f1c008143c16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3907 zcmb7HUrZax8K3pq*v1Ps|6(U_uz=Fq35S7;nh?kZauFd{*J%~*uC*F0<6XD~+iPYQ zsL^u0hdhu|)R;@8o~F6-{yr^K>dphjL%#m_B=qWA``lSICK|r)Du%t5<)4H zkB%Dpq^C-QJueWeh({rcLm?AKg=o%n7lq6m4XuSULtDjJptYu|d{(VywC_ja{H>%c z#DztEv70qWHZIPyvdGGx@@x|G^MW`hu|h(U@my3E!~`p2o{t)#lG&~Bqv5yr5Q14n z3ZLX);}p(&Rj$Y*C}Y)UM4J&Pf9(75=7&5 zg^D>98ZXEWLy0q;G=d7f^3@wrlp>upEmk39#7!Z&#+d7*9t_*-=uR6#OXjj@X~hgH zJYsgmd>W=XJoo)}GfKgq&m8=Ygtzz}962kN&YVp~B#FJuPGT|6iZPBo%aL=20~Xl? zzhDd(?ZCgxo|V{YfQ=Ot1A-)LRnk~wBF1Z0P}Lc9j8AAaoLGh`&631ILe?xel9=Ls z7R@a2u}RHFW+671oW5qA=kbIn@fsya7GSXCdv($OsTk*DVl)!-&&K;M^<22n=O0Z? zVDSc@C=vni>aT!tcQU2f!eJpH$l>tfsY;o_hvPxgV`x4{1$W!B`94!P)dHQP;6AO7 z9Lz&HeSI~s63DsQw;b&S#+7GURi^bh!@g{8+ZbFQT)uuk@U5f%1yh%882x+aH}XG} zzbd&8f4)5)$wsI0QBjSGx$$K7=B(NI3qt+9w|?UAN?}hc~L!e@ww~LziCj|u^^^l4?;yza>0y`06@QRKZR2z7jC)) zK0|@@#;rzNr16WEAp#fk!TzN;c>S*3}ypuVb@90xI`nEeRJZsAL2i5*yuK&l`v7hC~ z1a(Zvjm>QJ&lEf@8;*6yhI8GyX~}!9sNO3%@70`VX!+)GBBy8VwCe24q@JEuzdx|$ z9QfM)&3Sd`<7_CJ+VA#;$XdNy8DT|7pwjFW@LnA8A zG;|&x()~nuFr#9gb{>oj%Gh6H-zdPwFQ{pkAwTF9YKmF}zfn_of0c@fGZ7x( z356N}+Z5^qD7s z9bpL{Y75{&Ju*Qi)ID+RM2aOE(SdSreI;+~d6uj6ctUTw;l9W32*xmZ9bQpaf<8MY zMFS?qCwcpC={qQ5%?_{ptt5H%HJcApGv->&PsYMO$)vlGU zwb>Q_vbDg}EK`MA=flo4w;EfCq|2`RjAREZ#btmoZB3H=H6}?e(7$_yS=L0n{%Jr zjBdGm3*A3hv*tZs)#Kf)+wz=$>1oS*{Hn+Q)RylVReMHrJs)m+epqPqtOmXeWIoB< zR2$#@Do|)_TB}rVJ2qnLvCZCfaplI#!&t39wo}`+ojX0qUh{zYf?0E~*;QNnub9_U97%U1W$m4T=1nQ?Hu6zH zA7mTQfsQ=#h0{(vY7- z7I+tZYreE=c3Ap%&s15Oc3th3j=d3zva}S$9*6m%a=%I T*r6$k`ft@B)v}AA(GC6wAb3Bv diff --git a/HybroLang/__pycache__/H2Node.cpython-312.pyc b/HybroLang/__pycache__/H2Node.cpython-312.pyc deleted file mode 100644 index 92fafc154f477e822bdba7512120646442595592..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16155 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 QQ(hIa?{mKxufkcs0gu2TTmS$7 diff --git a/HybroLang/__pycache__/H2PowerRewrite.cpython-312.pyc b/HybroLang/__pycache__/H2PowerRewrite.cpython-312.pyc deleted file mode 100644 index 33cdab472d7de2e387575e05e5dfbe1d3d91b5d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2865 zcmZ`*U2Gdg5Z=8z+ZX4YrcL6csi7CqlpORY4Q&&kAT=!{fC;53Lb3pJ@m&&!^PRJI zX>03BE76C5A{w5ON<}SCP!&WGLckM6LZXNVVj9%2BvK`wcq<7KQlFT;%h`@q*7EG^ zezP;Xvoo{zb1W7`(7yWccJ}cwLVvPB(1dkn%>-r+X-LBcO8GrbVHk4;m*Z1BW^=qD ze8zd4V1#nvRM_J~MkFVuM2`;}b-8FN>hTeyJ}0Flj5suaH1Ryr>aKCVy;Q7#mFQn= zFr;8AJY!DfpvR8@i4FD)7jh$(aY7w2beNC^dy?viULJ=Bdxk8HAyJ<@QON5VU$IZ| z`e1DbFmp&p>?A2p!{5aI;{nxqz^U)}`(F-#j0xG~y5r=3f&m2z$m1M>VJ99Cy@iOF$Y8bjEk6J|Tw2MtO zXkNALV&b{uvO4PMM7|#y?$n;>w4;hhqob;$8qW}75im@$rb9($cu39ZG-4TAGHW|D zV(Ok02Y%E7NWlh^5QyC{~nZA;fIvKHS zo#Lz=f@8_7-Rs*sZsl~tf-~)%%=Pqj@893Ecd#%*tO4EhnIxFmyYU!%@&ziU(^)g? zq|?RL8ZZDFz>3YT{v2AW-!eNsf3g(cd1bN`SAMNmmZkVY+rjInZ-h&|12=K0_xV!W z^NZ38zt?YBmNqYJd3aIkT56N8#7k{mpKLC*JvuGS#FkojLMJV?ZuL4*x-GVq#I{AT zJy_PgDD7KrX}|Q?ymQ&T=-%44>sHI|RfJ=`vv|3&Wwvmom47Z7dj4< zS`Ylzc<^r?1n!2A)U*cMMVWH)zyQ+4PdC3PL0B=7ng$`b6G9NX=ro=vCrU*KRxzK~ zG#3XUT!i4yaOtw$nJyNPSMiX-lg+S-Yymnt7&eVOMZ|9AJz3uA6=3fFC^bf&L6#<=q@F?ukW~( z=q*XT?T;DnqEtk9w+1cw}vOWkuUE zZ5AX7Ps3K;E0j@3B`ic((Tv*G6v^m}S0u`3?S2{?SM3uO2{s%q3qkVO{f7y=Hp1Q- z%7abP$vBbOWY0OR1MM&Qwqn3mD}!N0nG*67GRi7rRyDu}ge3-zWO8}-nLr~WnG9np zCD>0`8KjC2)`Wdcy6*rP`yC+X&>bm0jhE`B3kTjkFw;9bId}Ghvx}`=pS=8e`f7S{ z_tQ5fe?0m9$sbNH#}k((E}Iw4Z#I9|{%!kW{OI%m%+0HpCoWE0-}m*CUp)EcQ#U7n zIs4PuTQ9x2VC8RHZ|G+V!s>V|f(;@l^c>E3=r8 diff --git a/HybroLang/__pycache__/H2RegAllocTmp.cpython-312.pyc b/HybroLang/__pycache__/H2RegAllocTmp.cpython-312.pyc deleted file mode 100644 index e834f28d8dc27bf11cda14445c7fa8adb19bea48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4591 zcmcH-TTC0-b;kDC2HV&P<`uj!n++k82T9121VY&m0afB%0Zmp!tu=TiU}JlnI|Ese z+092jV4EtSRx*54kX6+s%1WD`O8HFxD)k3rB3q-Z6tz+%R8^vhs#g2ebMANy7@DY+ zdL^GZ_uO;OoO@pPjQ{BIlru1X_v>8bFBJ^)XPlVBRzTkN0+MDVMq*=3oE>6W#4RyP z+&W~XxHV>rb3+`(Z83Y?G2~zw3)90$+yh3kKeZT=hMbcQ!MTAGfz=(ot=;nQ_z0l( z-qxTZ$$*s`*x+OmXFx|RY-~3mTbR6U0VK`H%n&OvLl%i0vPzZ*%#cm80^}qcKs&yF z$RXJQ(s%2g-qwD3q$?Iv!h`YT)W2X7Q8k(HB9cTcq9ph`3gI<5o>YiPB64{-4}V#psH zji_52wuP96BPYhZxCgw`H42p4C zul}#bOCbMrc^?}L}9R{`8-@-A=A)v)Gjc;()= zy1!-JeKKDYn6W){=d1DIG9L#TmQF050E#zX_rX%#V%_rTMPT@a=Pig~!e)Nqgo7Uq zj2D2UnGt3hoV{0YbTdD#VVG$P21B&ye%MqPDT^5}BkUB|YnpvnX9Jf;i@{-Xf++>f zVa}cwkZEhm8Z9%aTThU%M@UKR6tJXNv+iJ!4lsfxIOV^@i+3>H!BI4&c`cq4?8FWH z;CwkT2zjp(A4~}zLwBl$ARzl;D%eORQXL8T9*rM1qH_`!F%=Jjz9wJ?MlT zRlC!3TPp$JRBrP9p5>&1lh=hGc{wX%AnTlFUef zXtIFU*r34aWni^Wl6V*B$aA6N86;_&Hhk6A7I;lF{GT)Nje-M1-^3GlOs&heG`f~Bh^~O{A>I3Pq`LVPz zuPjTs!{NLG_nALcx6imX%bBVJGi7;~ zf1!NMb?_Ot453)N>a5)zix?Z!1~U+qG!}tSI-s^d(m^!5r?Rlj!z!pLY!r`DGR)YT zV+q(9c=m`&lZQt8-ze8RqLgy|9CUJ(yb7iue>V|2Cd|cRbi>v7U+lH+*lUBmc8PTc|0!+7LZI?NKaJ2Ym=FtsD{d-Sqv_2$-;U9zDlcyfiOo%*Se=WqrtidDX3nEU7+F4|DC z3{%P04iGfiy~Ic~7T)h$>W2?^3n-p+_T7G(cD%Zw z!*T*TdxgIfNl3*HfJtny6WGer_P?c^R!;yy+I(){t*UcyQ)#2R2`(QZ$cIH97;l^oh3#ZUU;7*jc*0r1=n1E;q!tVgjIrvBNvgcOfBA# zUO>0shQ>t+{f%byH)ti@8c}Z%Y*O_~ydkbCgve@ANl0QMEUP-JAxFP%7n4b7oeB00 z1WT*#yxG;?*Y)xBYeE^lVF;QUT4KX7^!Wge+9eVXEyCjRbBeV{0(fD_?hm!+xO_k?2Uy(FWrsUBJrC} z21uQ=oiAO1W&eslC$wdRwybb@?ZeA?Z{?hp{$l=%Y)$i;xA}E#V9C4aU9o-VdE$8{ zW{zCU*0#-Y`Tsx;@VP)sCeX4n{!GpW+ULshK7YDmzG7i=-6sH^^Bv0g4lNIUbNlh_ zTvJ=7sqMLtZR%e4UE4g)`227`HZlI%TxD~nvN>BRtPHMIp3d`!zNvUzk>yX#_2psF ze9g=$tTR%C0B%yF**2ba&S z)I7fO?A-IZ%$ch%e)5OQnQOPQfzLq8=2N-m?o4wx5HI}xXPM@~xw5ot-nGyJ+TsyB z^PUAUbRc>hRclQ*7NA2RF^QXwMLYFFE)UNO-90*o^F`)IRzRho5dOg+DWluLj?CI{vdkvq$%rlCifka%#s8O2*7I6x^xw t56*Vu_*ckhz=CB)Z3F;e&$9opGpz7E)BHVi4B$U){VeN$!yu%J{~LT><0b$A diff --git a/HybroLang/__pycache__/H2RegCSI.cpython-312.pyc b/HybroLang/__pycache__/H2RegCSI.cpython-312.pyc deleted file mode 100644 index a763dee5fd1e383ded79d968a32858cd80077c8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5373 zcmbVQO>7&-6`mz``6E(ZN)#>9vZ;+l*`(;mi7ZRD>qw?${k0BlONt8!P1qH8O_Sk| zvP;>bKmj=zC=CdR+>30aL3rpvfqU?!fQ~*EC{TDsrAsW5!bMNHIaZ4TzO-*2EMCV{?3 z&szkB&=#Prf)!S6f(?3m!5(VSY*Pa>Vq$D|nzv90jpZ_#T$YoU7C3QvQ4(c23B#ly zX7kBg$vB_K!_%B3COAHw&gm2VEiD|hK5km)D{%4VVzONRw#elrQS9d?auS!#-8Ezv zh=||}7YuX3JG=xUvT{BY3e`maLKGLdTvp`xtYEwv2HdUWvM6AEl5$>@YRuQACE(1# z%cO%xSttPWVw#U9vk9Wj0Rcop+_LAcF>Qwb-M_&7Y@i~O+Oueok|U3KNE4{Xz=<1$ zic}HBjE{wiCK%QEie?xY=7r@FBh+^qJ#f@@0ggk)eB&vYd@uk$n=zNbBm2HlU2>7S zf?DnT8KshouKkv#wK`k6Ul~z6^5L-ejf?6YTI|VZbMGv**M#(4WF%mLQHfe zd_6Kd%Ux)gGeznEW=MBP_sL|)L?gqV+t%lSH&IW1;22cMQ;wQvReMswHvRRo?$ zRv<1CvTL*~rf+G?G}c(c*D101j11^JoyE!}WX%e2KyhNzn{NFg+p0$teI4@N@kCx~)XZ0|CIE=>;|Cet+dK+fgs_)pBzDK_D zyN@tKYt_${=p9>E{n>eR+csL7d?={?A;mxRfZF$-()V7acSPwL z!SD0FupqXrWCm?tB9ncvH2J*!u-e|IwD)ZeSK80qAN!tx>0LM^(&%JX&c^Ft0aKVJ z&~sgf9x7D>7R+z7$2CHx3RICw?cHBn(IFxQE_1N`^#^E z(_Xa*<|6YsCD297=hPQ8j?vAsh9Yqic^NdoFngfEo+eRW-(!3OoZF;42R6d6Xl-x^ z%Lr*B@iKnK!(Q5j7P4-G%7Y1GHFi8W(fiiM6l!*Nm}0~y@NUJVsQ+P;!$`FNqSiK+PeG_2@6*&!Vv~vv(Vb?wXkw zgc?F&JtSJA1O(Q|kyeh@p{z+7f^R~e24sam&$?B%M`3%)lK@`d96M3ItDYQIP7YU&or93v zI!QgSubbEBs=-rg@RAa|^t7WAoLIN2E>3ZAW%stL7eX?yJ$D}|MW4GmRM&CEb-X-W zafM5fs<&J91{E(xId53?4l3TkCpQ%Duc|acNBzf|AEPF? zYNvPIMgVyq7GrD0|GUdZDglFot%g|#r(s-MsoDHq2EzweP2i(@7i#nyWa?=4hO}hW zoUbE0_;|g-X}re38i)wdT121$SDV&oKj93P*X;apO|3;s(WECrYZHJTwWMh6YLSkc zC^UNv6E9@RsDTeMzBWBYuVot2FwCqRuDj$uxEY5v8GlsBEj+%B4ZjjeZ7 z{l~w|Jj!fF6o0?!A5r`x75}Bu)&0{K75~MGf24G+%62`xTVYRZj&7wY;i+opk>9qw zu!FD{Ey&gWLvzQlM$G*w5RiH_HO*Qn3`KdWiD4H_hH+7-Rth&U)kcaSg#{?~o2DZ5 z6bBoKbeNRQO^mr{l*L$k(h4U07c#G$=4QnBk|ZbZh@2qGarixk%je+N5BN1iFUp{R z<%O2|cb2|ppAFz0qrI==XJb?hwf7ZMULmF z+7VDX0=R4nm#&biDWEt5<+-n&eYi*pKgT6px8mq7TX!76&6y{I>X~un%=ptpDr1l787#u zSWM~x)%56w!wZQ*`swk}zCwD+it}y>e+klILhgs|9{S#7Wo$29Zf5YsDJ#=a9@<6l zc+u`=e49YS<7JOe3 diff --git a/HybroLang/__pycache__/H2RegisterBank.cpython-312.pyc b/HybroLang/__pycache__/H2RegisterBank.cpython-312.pyc deleted file mode 100644 index 0f632f268eecbaa51ae050b2ddd4f4aa5d7e581c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8261 zcmdT}TW}LudOodI>n`Mre8C1!+r~Dsjg7%vm&=&3xh&vW@R$Ly6HVLQwq@&Lx@Evx zIXEe*Vp61l%2wg6olQ($MiiA@^NyNu?^s<-bp#^Y^*@|M|c3oul75oi+mLpMJIM|FnXTf5VqdvZOO>pF`#@5sAnI zh!>xR024HL4GiYl0Q--SGmv9MG+rknCm9~F`j=j#Xo5d8l@^fJFU($!YT7{4{=ksd zGfgud$M^Ws?_o4!UuY@_Po{NPuh%7$ep#!A%v~Z8FC!AKL1etFXn?L*FE?%Ua9Z{8 z9cQIczY>w;oP~?l^fbd zArzD%V_}hx2osV5bzr+mK?bWp_`!Qb;n768g|P)RB{dgl_+i28A$SGs$6p!q50BC2 zY3oty3Q*7ZjUUPc9yTO|MB04D&si;hNc0a&N_Nag!*Xs=<6D@&5|$_0`707XEK3;m z0~ILCFUW`;(4shSE%80lDFGW^f7H8{NnFl7V3pTEdo+|kbOZ0C2i^LyI)eeHZ#cRSzF(ec^3 zO;LY6T|9cWudkgS9O&!KNWCOiVgvkV*&b)IIrOmZ(jutGD`VlQfXGiNxsjKTve}lv zK<|LntSSZ4=!gB`2rq@gQ=?Kv*Rrdkk_tG@vnxg8lP6wUFEl`KY_V zIP|Mls8P`Nvm|AA-8%5s2UZ-VKX1G({;lU*$EH=5II8J%G!sP-U*5FP6LebNL1%YK z1YY$Nqc}QafQjasAyaEWkLy@F!@gCAYR&*&zoi|Dq%)kA#JKS+mZ!UdMya9lIyoG*&td5nvh4uBr)BD%f>dM-M?ap!tJncRbPrk8wn1^TkWo?xBW z13qAGT8p<5v%ZJ5be*?bOV>$TD`qTatC%In9`Dc)NqXGU``PQ}w2@FtA^j;xqA_NU z8Ac5G`)bTQKpIJ8Lq>TEk!>@!3&4P9Y=3UM*{naWFjvS`_5!)W6zDe1*doZLXad_J z2o$7WG9niOjKl$K~C zY$*Kz%VF53GJuvtkf`1(rp05|%AooqKuJlNgk4bx!G=n4QUf+9N>_8x6W5hyoRFp! z&2~-*Oi4PtVwB4~ip?NAb_xZu2Me<3s@b6zglVKqawFDtfY3NB4r}Igt!57cYmj|9 z%Q8q;6+399Q5PRN^14Q)NWXM7ayCu#qICrrQ&5jxDOUi;X32LY4GX)~lGZscRk87| z?~ZR_P_1Z-_ox*ebGB4v&E4>w@PedPw#Uz?m7RdMuNSQv%B@}|<^EvV-K4sko;M#_ zZvIeh{xIq8nd?ir>*lARbgplue&2HakJS1f&7GX*R7YK^vVNgSt=u|yY}H_MR-_tR zzC3*I@N(lGwQ*0fao-DKE)TK7}&D)C=@omd|m&$i7wj}xe^IWR7dAYV-t!ocm@|#}6*-d(};xrMG^3se_>0a>fkby1EFvCXD8x~-2Ruke7xp_g-_ltb?ory<4N*FcW1K#mv z%t-N@dutyQBX!Lj+$yp&AnylMK8#!)@QI7U9HKy8qJT#;?9G!#5@QF5hf5$xzxZHa5xAK=DV0(8}%^6opD}S!ccmMt2UmT9_Qfs>w>($!sWYw-@>FyVV zwRX?-q}uo2#%m-E;QWSrNLEE*S(a%8IfJ1`5&% zj$lmY(gMtF=%>eL4>?u4aVKfj|3@)miP@O)F8@Vtr4&`mc@c-};2bRB&Q$0b~hIO#h27H)#gwD=Zn z$b?QFl_|2sW2TsyQW-90rlIp@DueJ}kY1xQ?0<{OyvYu^ROU@~$fYu-;w|lcg8yrU61h#_?EEknr$7!sZj4X{0xJ9-^s$-fS;IZ*p~!-ry}0O#o2u z-D`&4+!P9X@R)Mwjf{vE^)x9!U^0-xHv+X0!*J||(={($#rvKt)A@j^9+jmxP$7>^ z-UdzTFo;ZG9Sh}7eBF+MM}ho>9$NB942I)6laagdwGjnvY$xWrQS1UyoUb@WV04+u zL~9GkN^a#Kwh^XGW#xZ^sgziUfT`3iySJ$BEenH5ciaC*Vp2`4&Rez{wuF1vV&tD^ z9?mRD&ju5_2UPdKx0X--@Y4D^HTll95sAqV5|c#Lk)__>o_>5fF>pTN^(8*~T&?aP;b`JBqSj_LW z_BFFlncBX3_Gvu_`8@E>GL-)S-@<7%yV=CxLL1>P3!7{t3%%fy?b518>B}Te%rQfhxWf>Y;aXgc?(Wa&R*MSrm0D|3zBGj$}Ldm;ntaq9^DQ2 z1%{@A2XababpFB$q8KeJh&w0?qV6P!S(1MtQ|#u&;<)9y;aaxTsg}A0E^b@wy6;>Z zUn+eVT)LQOIg|L{>~qUN3bb&gmUk`ospb2gTlS|*Zg+ptI4}Ovqn0;*YuTc+lI&7| z5uo!ZEBQMpg`Z&HdbZeY4LW58>#|D)zDuWKN9&y3asj?H#2C0prU%|AI1XB3M0OnA zQjj9q#e_fg6z?xa7nI1+MVuZ_#_ggB7r}e?Vg5hp!}5+k=T~h1{W6{h?aY!m7r(T)6~qSx0~Rh~7-r2x82j%@#R{o- xY2+B&eB>p8$La>MxglP$IJnf5_{m`6&%{JfRx6YQDf>@DkYUPR5R`Oq{{{S~3E}_% diff --git a/HybroLang/__pycache__/H2RiscvRewrite.cpython-312.pyc b/HybroLang/__pycache__/H2RiscvRewrite.cpython-312.pyc deleted file mode 100644 index 0a7d9dc586639dd4659221cb7b1844eb9daa2389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2632 zcmZ`*%Wo4$7@zU(+8cZGfINZVZg{0G)Pe8_3Mr-H6(q}%NXo&YayQ;d;&i?1%x)fb z7l{LhP(>x}B|)MhoC<7nW$(TfAF2-`$L>Zwu>G&xk_)NgiU$Fb6}JoC+b^L_Kp z_xR2JR$CiH(0=*hb@~%OLVvPJsqtIHrVhjcQjv-^l<-EJz%ch|z6_V(Fk9m^{wJSH z@tTnFC;TogXn~BF5MA1@)ntN+pi2j|P)15f82Qk3q>A^DTJzlJotLQ1;Yjc=Hi<{D z!(Y`WGce+hpsVfg9?WHi4Q)sn)(9*}{oOHTn3U)K{_eP;GEUH=hH_bw@)UbL-kNM4 z0b&6W#BP%CsrVjBaH7kq^_j>am^5wg-)uixf(m$mtQ zplHOm^Y(KcJj%f@5{NqjWsc3a@AR;oQZ$XI@`yp@qh`LbiknqT6G9xAB6Qd=NxuEY zO<5VS2$gr)nD-x5dyksIi0A}I6id;rQfg2~$kMcKIif;SV{s)zoPeRJv9xJ90i8^{ zM2LFvzM-2s7^>)_#NjleM+ApAi8kVhSxvFP#*9;+)=i5}rmVD~Gg->q>)^C0z$ml! z{(RS%ks+D^SL>R{be}(Y=1g~2e{Pr>*NN^CF*u@Y=M|#aoFgWaX+3Qvllj&vW{FV; zre zSBGG|g{`}x;~}8B$x07mNB6V!M(FbUt0GX5BJIF8qtHPRn%Wj(-^IX9HGQ*JR;7jq zv2S9FR~`>M9C$jk-1Dma!isd^+ZcGMrjIhYRM||JFxrI_cI^K-Xb{mbup`*L2Mo-1 zlZkrfI(4JOij!%UyeuR02dgaK$(EV41RWS(-}u13Zx_S^o@r(L0WL!y*R;QZU}$%T zv$^p~<6)h(=iY$mm%!g8ekx|jp!!^_j9cYcT7Z*Y+YO6$*Y$!c#rzI$`{-e-jEiao z7FMhZHeZs!sAAo3mo))K^EMv!4Z@Zi6tK|Ng7!~6$Tcv4$qb8)OZ?WM0fBhfHuF8WiMAg`kAVx z^-<7u>+(SSn!8&bCV)9aw#JB@nxvHImb)H}M)Oj|w%&aGB5Y%%&hf*mp&A*7GjpcH6Zn*&9B`aKfA{BBS~Hzi z_XS|UAKme7Ls>;QEtTBu4;{*i#A&ExvVgd;begJ{St7X+cCDujp|-E}UhMPyagoAT viwiww1c-MW#(2|@aNQp$xQ?3FQ1d!EwT@1%qa*9+#J~I@9Ns|CxvKsHSovhe diff --git a/HybroLang/__pycache__/H2SymbolTable.cpython-312.pyc b/HybroLang/__pycache__/H2SymbolTable.cpython-312.pyc deleted file mode 100644 index aaace0efb33822512a1d826ed34ad4ffe4fedacf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4311 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 diff --git a/HybroLang/__pycache__/HybroLangLexer.cpython-312.pyc b/HybroLang/__pycache__/HybroLangLexer.cpython-312.pyc deleted file mode 100644 index bcce46c9bdbc7fab9b3a2f2f204b1b41bb3a5acf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13941 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 diff --git a/HybroLang/__pycache__/__init__.cpython-312.pyc b/HybroLang/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index ccec25cde21043933408714bdb761a12860a07d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmX@j%ge<81Y74`&jitrK?FMZ%mNgd&QQsq$>_I|p@<2{`wUX^%Sb;XKQ}ceKRGc+ zzcAOx!obADNZ+F}sVLt)H4nn@Nz6;vkB`sH%PfhH*DI*}#bJ}1pHiBWYFESxG=dR` Qi$RQ!%#4hTMa)1J05Lft8UO$Q From 0ef1afed6c26a74f6badbb3b5e9f9fc72158bb7f Mon Sep 17 00:00:00 2001 From: Quentin MELOTTE Date: Wed, 22 Jul 2026 15:52:50 +0200 Subject: [PATCH 4/6] Delete file Antlr generated --- HybroLang/.antlr/HybroLang.interp | 125 -- HybroLang/.antlr/HybroLang.tokens | 84 - HybroLang/.antlr/HybroLangBaseListener.java | 327 ---- HybroLang/.antlr/HybroLangLexer.interp | 162 -- HybroLang/.antlr/HybroLangLexer.java | 329 ---- HybroLang/.antlr/HybroLangLexer.tokens | 84 - HybroLang/.antlr/HybroLangListener.java | 255 --- HybroLang/.antlr/HybroLangParser.java | 1680 ------------------- 8 files changed, 3046 deletions(-) delete mode 100644 HybroLang/.antlr/HybroLang.interp delete mode 100644 HybroLang/.antlr/HybroLang.tokens delete mode 100644 HybroLang/.antlr/HybroLangBaseListener.java delete mode 100644 HybroLang/.antlr/HybroLangLexer.interp delete mode 100644 HybroLang/.antlr/HybroLangLexer.java delete mode 100644 HybroLang/.antlr/HybroLangLexer.tokens delete mode 100644 HybroLang/.antlr/HybroLangListener.java delete mode 100644 HybroLang/.antlr/HybroLangParser.java diff --git a/HybroLang/.antlr/HybroLang.interp b/HybroLang/.antlr/HybroLang.interp deleted file mode 100644 index 8ea5afa..0000000 --- a/HybroLang/.antlr/HybroLang.interp +++ /dev/null @@ -1,125 +0,0 @@ -token literal names: -null -'(' -')' -'{' -'}' -',' -';' -'for' -'if' -'else' -'return' -'=' -'[' -']' -'*' -'/' -'+' -'-' -'<<' -'>>' -'&' -'|' -'^' -'int' -'uint' -'sint' -'suint' -'flt' -'cpl' -'pix' -'ipv4' -'ipv6' -'[]' -'==' -'!=' -'<' -'>' -'<=' -'>=' -null -null -null -null -null -null -null -null - -token symbolic names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -DecimalFloatingConstant -IntegerConstant -DecimalConstant -Name -INLINE -WhiteSpace -LineComment -NewLine - -rule names: -compilationunit -function -fndcl -fnprototype -fnbody -paramdcllist -localvardef -vardcllist -vardcl -actionlist -condexpr -action -returnexpr -affectexpr -unaryexpr -varorvalue -datatype -intconstvalue -constvalue -constinline -typebase -condOperator - - -atn: -[4, 1, 46, 204, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 1, 0, 4, 0, 46, 8, 0, 11, 0, 12, 0, 47, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 5, 4, 63, 8, 4, 10, 4, 12, 4, 66, 9, 4, 1, 4, 1, 4, 3, 4, 70, 8, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 5, 5, 77, 8, 5, 10, 5, 12, 5, 80, 9, 5, 1, 5, 3, 5, 83, 8, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 5, 7, 91, 8, 7, 10, 7, 12, 7, 94, 9, 7, 1, 8, 1, 8, 1, 8, 1, 9, 5, 9, 100, 8, 9, 10, 9, 12, 9, 103, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 136, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 152, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 169, 8, 14, 10, 14, 12, 14, 172, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 181, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 3, 17, 189, 8, 17, 1, 18, 1, 18, 1, 18, 3, 18, 194, 8, 18, 1, 19, 1, 19, 1, 20, 1, 20, 3, 20, 200, 8, 20, 1, 21, 1, 21, 1, 21, 0, 1, 28, 22, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 0, 6, 1, 0, 14, 15, 1, 0, 16, 17, 1, 0, 18, 19, 1, 0, 20, 22, 1, 0, 23, 31, 1, 0, 33, 38, 201, 0, 45, 1, 0, 0, 0, 2, 49, 1, 0, 0, 0, 4, 52, 1, 0, 0, 0, 6, 56, 1, 0, 0, 0, 8, 60, 1, 0, 0, 0, 10, 82, 1, 0, 0, 0, 12, 84, 1, 0, 0, 0, 14, 87, 1, 0, 0, 0, 16, 95, 1, 0, 0, 0, 18, 101, 1, 0, 0, 0, 20, 104, 1, 0, 0, 0, 22, 135, 1, 0, 0, 0, 24, 137, 1, 0, 0, 0, 26, 151, 1, 0, 0, 0, 28, 153, 1, 0, 0, 0, 30, 180, 1, 0, 0, 0, 32, 182, 1, 0, 0, 0, 34, 188, 1, 0, 0, 0, 36, 193, 1, 0, 0, 0, 38, 195, 1, 0, 0, 0, 40, 197, 1, 0, 0, 0, 42, 201, 1, 0, 0, 0, 44, 46, 3, 2, 1, 0, 45, 44, 1, 0, 0, 0, 46, 47, 1, 0, 0, 0, 47, 45, 1, 0, 0, 0, 47, 48, 1, 0, 0, 0, 48, 1, 1, 0, 0, 0, 49, 50, 3, 4, 2, 0, 50, 51, 3, 8, 4, 0, 51, 3, 1, 0, 0, 0, 52, 53, 3, 32, 16, 0, 53, 54, 5, 42, 0, 0, 54, 55, 3, 6, 3, 0, 55, 5, 1, 0, 0, 0, 56, 57, 5, 1, 0, 0, 57, 58, 3, 10, 5, 0, 58, 59, 5, 2, 0, 0, 59, 7, 1, 0, 0, 0, 60, 64, 5, 3, 0, 0, 61, 63, 3, 12, 6, 0, 62, 61, 1, 0, 0, 0, 63, 66, 1, 0, 0, 0, 64, 62, 1, 0, 0, 0, 64, 65, 1, 0, 0, 0, 65, 67, 1, 0, 0, 0, 66, 64, 1, 0, 0, 0, 67, 69, 3, 18, 9, 0, 68, 70, 3, 24, 12, 0, 69, 68, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 72, 5, 4, 0, 0, 72, 9, 1, 0, 0, 0, 73, 78, 3, 16, 8, 0, 74, 75, 5, 5, 0, 0, 75, 77, 3, 16, 8, 0, 76, 74, 1, 0, 0, 0, 77, 80, 1, 0, 0, 0, 78, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 83, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 81, 83, 1, 0, 0, 0, 82, 73, 1, 0, 0, 0, 82, 81, 1, 0, 0, 0, 83, 11, 1, 0, 0, 0, 84, 85, 3, 14, 7, 0, 85, 86, 5, 6, 0, 0, 86, 13, 1, 0, 0, 0, 87, 92, 3, 16, 8, 0, 88, 89, 5, 5, 0, 0, 89, 91, 5, 42, 0, 0, 90, 88, 1, 0, 0, 0, 91, 94, 1, 0, 0, 0, 92, 90, 1, 0, 0, 0, 92, 93, 1, 0, 0, 0, 93, 15, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 95, 96, 3, 32, 16, 0, 96, 97, 5, 42, 0, 0, 97, 17, 1, 0, 0, 0, 98, 100, 3, 22, 11, 0, 99, 98, 1, 0, 0, 0, 100, 103, 1, 0, 0, 0, 101, 99, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 19, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 104, 105, 3, 30, 15, 0, 105, 106, 3, 42, 21, 0, 106, 107, 3, 30, 15, 0, 107, 21, 1, 0, 0, 0, 108, 109, 3, 26, 13, 0, 109, 110, 5, 6, 0, 0, 110, 136, 1, 0, 0, 0, 111, 112, 5, 7, 0, 0, 112, 113, 5, 1, 0, 0, 113, 114, 3, 26, 13, 0, 114, 115, 5, 6, 0, 0, 115, 116, 3, 20, 10, 0, 116, 117, 5, 6, 0, 0, 117, 118, 3, 26, 13, 0, 118, 119, 5, 2, 0, 0, 119, 120, 5, 3, 0, 0, 120, 121, 3, 18, 9, 0, 121, 122, 5, 4, 0, 0, 122, 136, 1, 0, 0, 0, 123, 124, 5, 8, 0, 0, 124, 125, 5, 1, 0, 0, 125, 126, 3, 20, 10, 0, 126, 127, 5, 2, 0, 0, 127, 128, 5, 3, 0, 0, 128, 129, 3, 18, 9, 0, 129, 130, 5, 4, 0, 0, 130, 131, 5, 9, 0, 0, 131, 132, 5, 3, 0, 0, 132, 133, 3, 18, 9, 0, 133, 134, 5, 4, 0, 0, 134, 136, 1, 0, 0, 0, 135, 108, 1, 0, 0, 0, 135, 111, 1, 0, 0, 0, 135, 123, 1, 0, 0, 0, 136, 23, 1, 0, 0, 0, 137, 138, 5, 10, 0, 0, 138, 139, 3, 28, 14, 0, 139, 140, 5, 6, 0, 0, 140, 25, 1, 0, 0, 0, 141, 142, 5, 42, 0, 0, 142, 143, 5, 11, 0, 0, 143, 152, 3, 28, 14, 0, 144, 145, 5, 42, 0, 0, 145, 146, 5, 12, 0, 0, 146, 147, 3, 28, 14, 0, 147, 148, 5, 13, 0, 0, 148, 149, 5, 11, 0, 0, 149, 150, 3, 28, 14, 0, 150, 152, 1, 0, 0, 0, 151, 141, 1, 0, 0, 0, 151, 144, 1, 0, 0, 0, 152, 27, 1, 0, 0, 0, 153, 154, 6, 14, -1, 0, 154, 155, 3, 30, 15, 0, 155, 170, 1, 0, 0, 0, 156, 157, 10, 5, 0, 0, 157, 158, 7, 0, 0, 0, 158, 169, 3, 28, 14, 6, 159, 160, 10, 4, 0, 0, 160, 161, 7, 1, 0, 0, 161, 169, 3, 28, 14, 5, 162, 163, 10, 3, 0, 0, 163, 164, 7, 2, 0, 0, 164, 169, 3, 28, 14, 4, 165, 166, 10, 2, 0, 0, 166, 167, 7, 3, 0, 0, 167, 169, 3, 28, 14, 3, 168, 156, 1, 0, 0, 0, 168, 159, 1, 0, 0, 0, 168, 162, 1, 0, 0, 0, 168, 165, 1, 0, 0, 0, 169, 172, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 170, 171, 1, 0, 0, 0, 171, 29, 1, 0, 0, 0, 172, 170, 1, 0, 0, 0, 173, 174, 5, 42, 0, 0, 174, 175, 5, 12, 0, 0, 175, 176, 3, 28, 14, 0, 176, 177, 5, 13, 0, 0, 177, 181, 1, 0, 0, 0, 178, 181, 3, 36, 18, 0, 179, 181, 5, 42, 0, 0, 180, 173, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 180, 179, 1, 0, 0, 0, 181, 31, 1, 0, 0, 0, 182, 183, 3, 40, 20, 0, 183, 184, 3, 34, 17, 0, 184, 185, 3, 34, 17, 0, 185, 33, 1, 0, 0, 0, 186, 189, 5, 40, 0, 0, 187, 189, 3, 38, 19, 0, 188, 186, 1, 0, 0, 0, 188, 187, 1, 0, 0, 0, 189, 35, 1, 0, 0, 0, 190, 194, 5, 40, 0, 0, 191, 194, 5, 39, 0, 0, 192, 194, 3, 38, 19, 0, 193, 190, 1, 0, 0, 0, 193, 191, 1, 0, 0, 0, 193, 192, 1, 0, 0, 0, 194, 37, 1, 0, 0, 0, 195, 196, 5, 43, 0, 0, 196, 39, 1, 0, 0, 0, 197, 199, 7, 4, 0, 0, 198, 200, 5, 32, 0, 0, 199, 198, 1, 0, 0, 0, 199, 200, 1, 0, 0, 0, 200, 41, 1, 0, 0, 0, 201, 202, 7, 5, 0, 0, 202, 43, 1, 0, 0, 0, 15, 47, 64, 69, 78, 82, 92, 101, 135, 151, 168, 170, 180, 188, 193, 199] \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLang.tokens b/HybroLang/.antlr/HybroLang.tokens deleted file mode 100644 index 574a34a..0000000 --- a/HybroLang/.antlr/HybroLang.tokens +++ /dev/null @@ -1,84 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -T__4=5 -T__5=6 -T__6=7 -T__7=8 -T__8=9 -T__9=10 -T__10=11 -T__11=12 -T__12=13 -T__13=14 -T__14=15 -T__15=16 -T__16=17 -T__17=18 -T__18=19 -T__19=20 -T__20=21 -T__21=22 -T__22=23 -T__23=24 -T__24=25 -T__25=26 -T__26=27 -T__27=28 -T__28=29 -T__29=30 -T__30=31 -T__31=32 -T__32=33 -T__33=34 -T__34=35 -T__35=36 -T__36=37 -T__37=38 -DecimalFloatingConstant=39 -IntegerConstant=40 -DecimalConstant=41 -Name=42 -INLINE=43 -WhiteSpace=44 -LineComment=45 -NewLine=46 -'('=1 -')'=2 -'{'=3 -'}'=4 -','=5 -';'=6 -'for'=7 -'if'=8 -'else'=9 -'return'=10 -'='=11 -'['=12 -']'=13 -'*'=14 -'/'=15 -'+'=16 -'-'=17 -'<<'=18 -'>>'=19 -'&'=20 -'|'=21 -'^'=22 -'int'=23 -'uint'=24 -'sint'=25 -'suint'=26 -'flt'=27 -'cpl'=28 -'pix'=29 -'ipv4'=30 -'ipv6'=31 -'[]'=32 -'=='=33 -'!='=34 -'<'=35 -'>'=36 -'<='=37 -'>='=38 diff --git a/HybroLang/.antlr/HybroLangBaseListener.java b/HybroLang/.antlr/HybroLangBaseListener.java deleted file mode 100644 index 1196c27..0000000 --- a/HybroLang/.antlr/HybroLangBaseListener.java +++ /dev/null @@ -1,327 +0,0 @@ -// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 - -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.tree.ErrorNode; -import org.antlr.v4.runtime.tree.TerminalNode; - -/** - * This class provides an empty implementation of {@link HybroLangListener}, - * which can be extended to create a listener which only needs to handle a subset - * of the available methods. - */ -@SuppressWarnings("CheckReturnValue") -public class HybroLangBaseListener implements HybroLangListener { - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterCompilationunit(HybroLangParser.CompilationunitContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitCompilationunit(HybroLangParser.CompilationunitContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterFunction(HybroLangParser.FunctionContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitFunction(HybroLangParser.FunctionContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterFndcl(HybroLangParser.FndclContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitFndcl(HybroLangParser.FndclContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterFnprototype(HybroLangParser.FnprototypeContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitFnprototype(HybroLangParser.FnprototypeContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterFnbody(HybroLangParser.FnbodyContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitFnbody(HybroLangParser.FnbodyContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterParamdcllist(HybroLangParser.ParamdcllistContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitParamdcllist(HybroLangParser.ParamdcllistContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterLocalvardef(HybroLangParser.LocalvardefContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitLocalvardef(HybroLangParser.LocalvardefContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterVardcllist(HybroLangParser.VardcllistContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitVardcllist(HybroLangParser.VardcllistContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterVardcl(HybroLangParser.VardclContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitVardcl(HybroLangParser.VardclContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterActionlist(HybroLangParser.ActionlistContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitActionlist(HybroLangParser.ActionlistContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterCondexpr(HybroLangParser.CondexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitCondexpr(HybroLangParser.CondexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterAction(HybroLangParser.ActionContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitAction(HybroLangParser.ActionContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterReturnexpr(HybroLangParser.ReturnexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitReturnexpr(HybroLangParser.ReturnexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterAffectexpr(HybroLangParser.AffectexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitAffectexpr(HybroLangParser.AffectexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterUnaryexpr(HybroLangParser.UnaryexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitUnaryexpr(HybroLangParser.UnaryexprContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterDatatype(HybroLangParser.DatatypeContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitDatatype(HybroLangParser.DatatypeContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterIntconstvalue(HybroLangParser.IntconstvalueContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitIntconstvalue(HybroLangParser.IntconstvalueContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterConstvalue(HybroLangParser.ConstvalueContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitConstvalue(HybroLangParser.ConstvalueContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterConstinline(HybroLangParser.ConstinlineContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitConstinline(HybroLangParser.ConstinlineContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterTypebase(HybroLangParser.TypebaseContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitTypebase(HybroLangParser.TypebaseContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterCondOperator(HybroLangParser.CondOperatorContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitCondOperator(HybroLangParser.CondOperatorContext ctx) { } - - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void enterEveryRule(ParserRuleContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void exitEveryRule(ParserRuleContext ctx) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void visitTerminal(TerminalNode node) { } - /** - * {@inheritDoc} - * - *

The default implementation does nothing.

- */ - @Override public void visitErrorNode(ErrorNode node) { } -} \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangLexer.interp b/HybroLang/.antlr/HybroLangLexer.interp deleted file mode 100644 index 9840595..0000000 --- a/HybroLang/.antlr/HybroLangLexer.interp +++ /dev/null @@ -1,162 +0,0 @@ -token literal names: -null -'(' -')' -'{' -'}' -',' -';' -'for' -'if' -'else' -'return' -'=' -'[' -']' -'*' -'/' -'+' -'-' -'<<' -'>>' -'&' -'|' -'^' -'int' -'uint' -'sint' -'suint' -'flt' -'cpl' -'pix' -'ipv4' -'ipv6' -'[]' -'==' -'!=' -'<' -'>' -'<=' -'>=' -null -null -null -null -null -null -null -null - -token symbolic names: -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -null -DecimalFloatingConstant -IntegerConstant -DecimalConstant -Name -INLINE -WhiteSpace -LineComment -NewLine - -rule names: -T__0 -T__1 -T__2 -T__3 -T__4 -T__5 -T__6 -T__7 -T__8 -T__9 -T__10 -T__11 -T__12 -T__13 -T__14 -T__15 -T__16 -T__17 -T__18 -T__19 -T__20 -T__21 -T__22 -T__23 -T__24 -T__25 -T__26 -T__27 -T__28 -T__29 -T__30 -T__31 -T__32 -T__33 -T__34 -T__35 -T__36 -T__37 -DecimalFloatingConstant -ExponentPart -FloatingSuffix -FractionalConstant -IntegerConstant -DecimalConstant -DigitSequence -Digit -NonzeroDigit -Sign -Name -INLINE -WhiteSpace -LineComment -NewLine - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[4, 0, 46, 320, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 3, 38, 228, 8, 38, 1, 38, 3, 38, 231, 8, 38, 1, 39, 1, 39, 3, 39, 235, 8, 39, 1, 39, 1, 39, 1, 39, 3, 39, 240, 8, 39, 1, 39, 3, 39, 243, 8, 39, 1, 40, 1, 40, 1, 41, 3, 41, 248, 8, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 255, 8, 41, 1, 42, 1, 42, 1, 43, 1, 43, 5, 43, 261, 8, 43, 10, 43, 12, 43, 264, 9, 43, 1, 44, 4, 44, 267, 8, 44, 11, 44, 12, 44, 268, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 5, 48, 279, 8, 48, 10, 48, 12, 48, 282, 9, 48, 1, 49, 1, 49, 1, 49, 1, 49, 4, 49, 288, 8, 49, 11, 49, 12, 49, 289, 1, 49, 1, 49, 1, 50, 4, 50, 295, 8, 50, 11, 50, 12, 50, 296, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 5, 51, 305, 8, 51, 10, 51, 12, 51, 308, 9, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 3, 52, 315, 8, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 306, 0, 53, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 0, 81, 0, 83, 0, 85, 40, 87, 41, 89, 0, 91, 0, 93, 0, 95, 0, 97, 42, 99, 43, 101, 44, 103, 45, 105, 46, 1, 0, 8, 4, 0, 70, 70, 76, 76, 102, 102, 108, 108, 1, 0, 48, 57, 1, 0, 49, 57, 2, 0, 43, 43, 45, 45, 2, 0, 65, 90, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 1, 0, 41, 41, 2, 0, 9, 9, 32, 32, 326, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 1, 107, 1, 0, 0, 0, 3, 109, 1, 0, 0, 0, 5, 111, 1, 0, 0, 0, 7, 113, 1, 0, 0, 0, 9, 115, 1, 0, 0, 0, 11, 117, 1, 0, 0, 0, 13, 119, 1, 0, 0, 0, 15, 123, 1, 0, 0, 0, 17, 126, 1, 0, 0, 0, 19, 131, 1, 0, 0, 0, 21, 138, 1, 0, 0, 0, 23, 140, 1, 0, 0, 0, 25, 142, 1, 0, 0, 0, 27, 144, 1, 0, 0, 0, 29, 146, 1, 0, 0, 0, 31, 148, 1, 0, 0, 0, 33, 150, 1, 0, 0, 0, 35, 152, 1, 0, 0, 0, 37, 155, 1, 0, 0, 0, 39, 158, 1, 0, 0, 0, 41, 160, 1, 0, 0, 0, 43, 162, 1, 0, 0, 0, 45, 164, 1, 0, 0, 0, 47, 168, 1, 0, 0, 0, 49, 173, 1, 0, 0, 0, 51, 178, 1, 0, 0, 0, 53, 184, 1, 0, 0, 0, 55, 188, 1, 0, 0, 0, 57, 192, 1, 0, 0, 0, 59, 196, 1, 0, 0, 0, 61, 201, 1, 0, 0, 0, 63, 206, 1, 0, 0, 0, 65, 209, 1, 0, 0, 0, 67, 212, 1, 0, 0, 0, 69, 215, 1, 0, 0, 0, 71, 217, 1, 0, 0, 0, 73, 219, 1, 0, 0, 0, 75, 222, 1, 0, 0, 0, 77, 225, 1, 0, 0, 0, 79, 242, 1, 0, 0, 0, 81, 244, 1, 0, 0, 0, 83, 254, 1, 0, 0, 0, 85, 256, 1, 0, 0, 0, 87, 258, 1, 0, 0, 0, 89, 266, 1, 0, 0, 0, 91, 270, 1, 0, 0, 0, 93, 272, 1, 0, 0, 0, 95, 274, 1, 0, 0, 0, 97, 276, 1, 0, 0, 0, 99, 283, 1, 0, 0, 0, 101, 294, 1, 0, 0, 0, 103, 300, 1, 0, 0, 0, 105, 314, 1, 0, 0, 0, 107, 108, 5, 40, 0, 0, 108, 2, 1, 0, 0, 0, 109, 110, 5, 41, 0, 0, 110, 4, 1, 0, 0, 0, 111, 112, 5, 123, 0, 0, 112, 6, 1, 0, 0, 0, 113, 114, 5, 125, 0, 0, 114, 8, 1, 0, 0, 0, 115, 116, 5, 44, 0, 0, 116, 10, 1, 0, 0, 0, 117, 118, 5, 59, 0, 0, 118, 12, 1, 0, 0, 0, 119, 120, 5, 102, 0, 0, 120, 121, 5, 111, 0, 0, 121, 122, 5, 114, 0, 0, 122, 14, 1, 0, 0, 0, 123, 124, 5, 105, 0, 0, 124, 125, 5, 102, 0, 0, 125, 16, 1, 0, 0, 0, 126, 127, 5, 101, 0, 0, 127, 128, 5, 108, 0, 0, 128, 129, 5, 115, 0, 0, 129, 130, 5, 101, 0, 0, 130, 18, 1, 0, 0, 0, 131, 132, 5, 114, 0, 0, 132, 133, 5, 101, 0, 0, 133, 134, 5, 116, 0, 0, 134, 135, 5, 117, 0, 0, 135, 136, 5, 114, 0, 0, 136, 137, 5, 110, 0, 0, 137, 20, 1, 0, 0, 0, 138, 139, 5, 61, 0, 0, 139, 22, 1, 0, 0, 0, 140, 141, 5, 91, 0, 0, 141, 24, 1, 0, 0, 0, 142, 143, 5, 93, 0, 0, 143, 26, 1, 0, 0, 0, 144, 145, 5, 42, 0, 0, 145, 28, 1, 0, 0, 0, 146, 147, 5, 47, 0, 0, 147, 30, 1, 0, 0, 0, 148, 149, 5, 43, 0, 0, 149, 32, 1, 0, 0, 0, 150, 151, 5, 45, 0, 0, 151, 34, 1, 0, 0, 0, 152, 153, 5, 60, 0, 0, 153, 154, 5, 60, 0, 0, 154, 36, 1, 0, 0, 0, 155, 156, 5, 62, 0, 0, 156, 157, 5, 62, 0, 0, 157, 38, 1, 0, 0, 0, 158, 159, 5, 38, 0, 0, 159, 40, 1, 0, 0, 0, 160, 161, 5, 124, 0, 0, 161, 42, 1, 0, 0, 0, 162, 163, 5, 94, 0, 0, 163, 44, 1, 0, 0, 0, 164, 165, 5, 105, 0, 0, 165, 166, 5, 110, 0, 0, 166, 167, 5, 116, 0, 0, 167, 46, 1, 0, 0, 0, 168, 169, 5, 117, 0, 0, 169, 170, 5, 105, 0, 0, 170, 171, 5, 110, 0, 0, 171, 172, 5, 116, 0, 0, 172, 48, 1, 0, 0, 0, 173, 174, 5, 115, 0, 0, 174, 175, 5, 105, 0, 0, 175, 176, 5, 110, 0, 0, 176, 177, 5, 116, 0, 0, 177, 50, 1, 0, 0, 0, 178, 179, 5, 115, 0, 0, 179, 180, 5, 117, 0, 0, 180, 181, 5, 105, 0, 0, 181, 182, 5, 110, 0, 0, 182, 183, 5, 116, 0, 0, 183, 52, 1, 0, 0, 0, 184, 185, 5, 102, 0, 0, 185, 186, 5, 108, 0, 0, 186, 187, 5, 116, 0, 0, 187, 54, 1, 0, 0, 0, 188, 189, 5, 99, 0, 0, 189, 190, 5, 112, 0, 0, 190, 191, 5, 108, 0, 0, 191, 56, 1, 0, 0, 0, 192, 193, 5, 112, 0, 0, 193, 194, 5, 105, 0, 0, 194, 195, 5, 120, 0, 0, 195, 58, 1, 0, 0, 0, 196, 197, 5, 105, 0, 0, 197, 198, 5, 112, 0, 0, 198, 199, 5, 118, 0, 0, 199, 200, 5, 52, 0, 0, 200, 60, 1, 0, 0, 0, 201, 202, 5, 105, 0, 0, 202, 203, 5, 112, 0, 0, 203, 204, 5, 118, 0, 0, 204, 205, 5, 54, 0, 0, 205, 62, 1, 0, 0, 0, 206, 207, 5, 91, 0, 0, 207, 208, 5, 93, 0, 0, 208, 64, 1, 0, 0, 0, 209, 210, 5, 61, 0, 0, 210, 211, 5, 61, 0, 0, 211, 66, 1, 0, 0, 0, 212, 213, 5, 33, 0, 0, 213, 214, 5, 61, 0, 0, 214, 68, 1, 0, 0, 0, 215, 216, 5, 60, 0, 0, 216, 70, 1, 0, 0, 0, 217, 218, 5, 62, 0, 0, 218, 72, 1, 0, 0, 0, 219, 220, 5, 60, 0, 0, 220, 221, 5, 61, 0, 0, 221, 74, 1, 0, 0, 0, 222, 223, 5, 62, 0, 0, 223, 224, 5, 61, 0, 0, 224, 76, 1, 0, 0, 0, 225, 227, 3, 83, 41, 0, 226, 228, 3, 79, 39, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 230, 1, 0, 0, 0, 229, 231, 3, 81, 40, 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 78, 1, 0, 0, 0, 232, 234, 5, 101, 0, 0, 233, 235, 3, 95, 47, 0, 234, 233, 1, 0, 0, 0, 234, 235, 1, 0, 0, 0, 235, 236, 1, 0, 0, 0, 236, 243, 3, 89, 44, 0, 237, 239, 5, 69, 0, 0, 238, 240, 3, 95, 47, 0, 239, 238, 1, 0, 0, 0, 239, 240, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 243, 3, 89, 44, 0, 242, 232, 1, 0, 0, 0, 242, 237, 1, 0, 0, 0, 243, 80, 1, 0, 0, 0, 244, 245, 7, 0, 0, 0, 245, 82, 1, 0, 0, 0, 246, 248, 3, 89, 44, 0, 247, 246, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 249, 1, 0, 0, 0, 249, 250, 5, 46, 0, 0, 250, 255, 3, 89, 44, 0, 251, 252, 3, 89, 44, 0, 252, 253, 5, 46, 0, 0, 253, 255, 1, 0, 0, 0, 254, 247, 1, 0, 0, 0, 254, 251, 1, 0, 0, 0, 255, 84, 1, 0, 0, 0, 256, 257, 3, 89, 44, 0, 257, 86, 1, 0, 0, 0, 258, 262, 3, 93, 46, 0, 259, 261, 3, 91, 45, 0, 260, 259, 1, 0, 0, 0, 261, 264, 1, 0, 0, 0, 262, 260, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 88, 1, 0, 0, 0, 264, 262, 1, 0, 0, 0, 265, 267, 3, 91, 45, 0, 266, 265, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 266, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 90, 1, 0, 0, 0, 270, 271, 7, 1, 0, 0, 271, 92, 1, 0, 0, 0, 272, 273, 7, 2, 0, 0, 273, 94, 1, 0, 0, 0, 274, 275, 7, 3, 0, 0, 275, 96, 1, 0, 0, 0, 276, 280, 7, 4, 0, 0, 277, 279, 7, 5, 0, 0, 278, 277, 1, 0, 0, 0, 279, 282, 1, 0, 0, 0, 280, 278, 1, 0, 0, 0, 280, 281, 1, 0, 0, 0, 281, 98, 1, 0, 0, 0, 282, 280, 1, 0, 0, 0, 283, 284, 5, 35, 0, 0, 284, 285, 5, 40, 0, 0, 285, 287, 1, 0, 0, 0, 286, 288, 8, 6, 0, 0, 287, 286, 1, 0, 0, 0, 288, 289, 1, 0, 0, 0, 289, 287, 1, 0, 0, 0, 289, 290, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 292, 5, 41, 0, 0, 292, 100, 1, 0, 0, 0, 293, 295, 7, 7, 0, 0, 294, 293, 1, 0, 0, 0, 295, 296, 1, 0, 0, 0, 296, 294, 1, 0, 0, 0, 296, 297, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 299, 6, 50, 0, 0, 299, 102, 1, 0, 0, 0, 300, 301, 5, 47, 0, 0, 301, 302, 5, 47, 0, 0, 302, 306, 1, 0, 0, 0, 303, 305, 9, 0, 0, 0, 304, 303, 1, 0, 0, 0, 305, 308, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 306, 304, 1, 0, 0, 0, 307, 309, 1, 0, 0, 0, 308, 306, 1, 0, 0, 0, 309, 310, 3, 105, 52, 0, 310, 311, 1, 0, 0, 0, 311, 312, 6, 51, 0, 0, 312, 104, 1, 0, 0, 0, 313, 315, 5, 13, 0, 0, 314, 313, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 317, 5, 10, 0, 0, 317, 318, 1, 0, 0, 0, 318, 319, 6, 52, 0, 0, 319, 106, 1, 0, 0, 0, 15, 0, 227, 230, 234, 239, 242, 247, 254, 262, 268, 280, 289, 296, 306, 314, 1, 6, 0, 0] \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangLexer.java b/HybroLang/.antlr/HybroLangLexer.java deleted file mode 100644 index fe6b304..0000000 --- a/HybroLang/.antlr/HybroLangLexer.java +++ /dev/null @@ -1,329 +0,0 @@ -// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) -public class HybroLangLexer extends Lexer { - static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, - T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, - T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, - T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, - T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, - DecimalFloatingConstant=39, IntegerConstant=40, DecimalConstant=41, Name=42, - INLINE=43, WhiteSpace=44, LineComment=45, NewLine=46; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - private static String[] makeRuleNames() { - return new String[] { - "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", - "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", - "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", - "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", - "T__33", "T__34", "T__35", "T__36", "T__37", "DecimalFloatingConstant", - "ExponentPart", "FloatingSuffix", "FractionalConstant", "IntegerConstant", - "DecimalConstant", "DigitSequence", "Digit", "NonzeroDigit", "Sign", - "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, "'('", "')'", "'{'", "'}'", "','", "';'", "'for'", "'if'", "'else'", - "'return'", "'='", "'['", "']'", "'*'", "'/'", "'+'", "'-'", "'<<'", - "'>>'", "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", "'suint'", - "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", "'=='", "'!='", - "'<'", "'>'", "'<='", "'>='" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, "DecimalFloatingConstant", "IntegerConstant", "DecimalConstant", - "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public HybroLangLexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "HybroLang.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - public static final String _serializedATN = - "\u0004\u0000.\u0140\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+ - "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+ - "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+ - "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+ - "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+ - "\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002"+ - "\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002"+ - "\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002"+ - "\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002"+ - "\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002"+ - "\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007"+ - "!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007"+ - "&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007"+ - "+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u0007"+ - "0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0001\u0000"+ - "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0003"+ - "\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0006"+ - "\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0001"+ - "\t\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+ - "\f\u0001\f\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+ - "\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0012"+ - "\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014"+ - "\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+ - "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018"+ - "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019"+ - "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a\u0001\u001a"+ - "\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+ - "\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d"+ - "\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001\u001e"+ - "\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001\u001f\u0001 \u0001"+ - " \u0001 \u0001!\u0001!\u0001!\u0001\"\u0001\"\u0001#\u0001#\u0001$\u0001"+ - "$\u0001$\u0001%\u0001%\u0001%\u0001&\u0001&\u0003&\u00e4\b&\u0001&\u0003"+ - "&\u00e7\b&\u0001\'\u0001\'\u0003\'\u00eb\b\'\u0001\'\u0001\'\u0001\'\u0003"+ - "\'\u00f0\b\'\u0001\'\u0003\'\u00f3\b\'\u0001(\u0001(\u0001)\u0003)\u00f8"+ - "\b)\u0001)\u0001)\u0001)\u0001)\u0001)\u0003)\u00ff\b)\u0001*\u0001*\u0001"+ - "+\u0001+\u0005+\u0105\b+\n+\f+\u0108\t+\u0001,\u0004,\u010b\b,\u000b,"+ - "\f,\u010c\u0001-\u0001-\u0001.\u0001.\u0001/\u0001/\u00010\u00010\u0005"+ - "0\u0117\b0\n0\f0\u011a\t0\u00011\u00011\u00011\u00011\u00041\u0120\b1"+ - "\u000b1\f1\u0121\u00011\u00011\u00012\u00042\u0127\b2\u000b2\f2\u0128"+ - "\u00012\u00012\u00013\u00013\u00013\u00013\u00053\u0131\b3\n3\f3\u0134"+ - "\t3\u00013\u00013\u00013\u00013\u00014\u00034\u013b\b4\u00014\u00014\u0001"+ - "4\u00014\u0001\u0132\u00005\u0001\u0001\u0003\u0002\u0005\u0003\u0007"+ - "\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b"+ - "\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011#\u0012%\u0013"+ - "\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b7\u001c9\u001d"+ - ";\u001e=\u001f? A!C\"E#G$I%K&M\'O\u0000Q\u0000S\u0000U(W)Y\u0000[\u0000"+ - "]\u0000_\u0000a*c+e,g-i.\u0001\u0000\b\u0004\u0000FFLLffll\u0001\u0000"+ - "09\u0001\u000019\u0002\u0000++--\u0002\u0000AZaz\u0004\u000009AZ__az\u0001"+ - "\u0000))\u0002\u0000\t\t \u0146\u0000\u0001\u0001\u0000\u0000\u0000\u0000"+ - "\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000"+ - "\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b"+ - "\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001"+ - "\u0000\u0000\u0000\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001"+ - "\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001"+ - "\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001"+ - "\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001"+ - "\u0000\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000"+ - "\u0000\u0000%\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000"+ - "\u0000)\u0001\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-"+ - "\u0001\u0000\u0000\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000"+ - "\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000"+ - "\u00007\u0001\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;"+ - "\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000"+ - "\u0000\u0000\u0000A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000"+ - "\u0000E\u0001\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0000I"+ - "\u0001\u0000\u0000\u0000\u0000K\u0001\u0000\u0000\u0000\u0000M\u0001\u0000"+ - "\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000\u0000"+ - "\u0000a\u0001\u0000\u0000\u0000\u0000c\u0001\u0000\u0000\u0000\u0000e"+ - "\u0001\u0000\u0000\u0000\u0000g\u0001\u0000\u0000\u0000\u0000i\u0001\u0000"+ - "\u0000\u0000\u0001k\u0001\u0000\u0000\u0000\u0003m\u0001\u0000\u0000\u0000"+ - "\u0005o\u0001\u0000\u0000\u0000\u0007q\u0001\u0000\u0000\u0000\ts\u0001"+ - "\u0000\u0000\u0000\u000bu\u0001\u0000\u0000\u0000\rw\u0001\u0000\u0000"+ - "\u0000\u000f{\u0001\u0000\u0000\u0000\u0011~\u0001\u0000\u0000\u0000\u0013"+ - "\u0083\u0001\u0000\u0000\u0000\u0015\u008a\u0001\u0000\u0000\u0000\u0017"+ - "\u008c\u0001\u0000\u0000\u0000\u0019\u008e\u0001\u0000\u0000\u0000\u001b"+ - "\u0090\u0001\u0000\u0000\u0000\u001d\u0092\u0001\u0000\u0000\u0000\u001f"+ - "\u0094\u0001\u0000\u0000\u0000!\u0096\u0001\u0000\u0000\u0000#\u0098\u0001"+ - "\u0000\u0000\u0000%\u009b\u0001\u0000\u0000\u0000\'\u009e\u0001\u0000"+ - "\u0000\u0000)\u00a0\u0001\u0000\u0000\u0000+\u00a2\u0001\u0000\u0000\u0000"+ - "-\u00a4\u0001\u0000\u0000\u0000/\u00a8\u0001\u0000\u0000\u00001\u00ad"+ - "\u0001\u0000\u0000\u00003\u00b2\u0001\u0000\u0000\u00005\u00b8\u0001\u0000"+ - "\u0000\u00007\u00bc\u0001\u0000\u0000\u00009\u00c0\u0001\u0000\u0000\u0000"+ - ";\u00c4\u0001\u0000\u0000\u0000=\u00c9\u0001\u0000\u0000\u0000?\u00ce"+ - "\u0001\u0000\u0000\u0000A\u00d1\u0001\u0000\u0000\u0000C\u00d4\u0001\u0000"+ - "\u0000\u0000E\u00d7\u0001\u0000\u0000\u0000G\u00d9\u0001\u0000\u0000\u0000"+ - "I\u00db\u0001\u0000\u0000\u0000K\u00de\u0001\u0000\u0000\u0000M\u00e1"+ - "\u0001\u0000\u0000\u0000O\u00f2\u0001\u0000\u0000\u0000Q\u00f4\u0001\u0000"+ - "\u0000\u0000S\u00fe\u0001\u0000\u0000\u0000U\u0100\u0001\u0000\u0000\u0000"+ - "W\u0102\u0001\u0000\u0000\u0000Y\u010a\u0001\u0000\u0000\u0000[\u010e"+ - "\u0001\u0000\u0000\u0000]\u0110\u0001\u0000\u0000\u0000_\u0112\u0001\u0000"+ - "\u0000\u0000a\u0114\u0001\u0000\u0000\u0000c\u011b\u0001\u0000\u0000\u0000"+ - "e\u0126\u0001\u0000\u0000\u0000g\u012c\u0001\u0000\u0000\u0000i\u013a"+ - "\u0001\u0000\u0000\u0000kl\u0005(\u0000\u0000l\u0002\u0001\u0000\u0000"+ - "\u0000mn\u0005)\u0000\u0000n\u0004\u0001\u0000\u0000\u0000op\u0005{\u0000"+ - "\u0000p\u0006\u0001\u0000\u0000\u0000qr\u0005}\u0000\u0000r\b\u0001\u0000"+ - "\u0000\u0000st\u0005,\u0000\u0000t\n\u0001\u0000\u0000\u0000uv\u0005;"+ - "\u0000\u0000v\f\u0001\u0000\u0000\u0000wx\u0005f\u0000\u0000xy\u0005o"+ - "\u0000\u0000yz\u0005r\u0000\u0000z\u000e\u0001\u0000\u0000\u0000{|\u0005"+ - "i\u0000\u0000|}\u0005f\u0000\u0000}\u0010\u0001\u0000\u0000\u0000~\u007f"+ - "\u0005e\u0000\u0000\u007f\u0080\u0005l\u0000\u0000\u0080\u0081\u0005s"+ - "\u0000\u0000\u0081\u0082\u0005e\u0000\u0000\u0082\u0012\u0001\u0000\u0000"+ - "\u0000\u0083\u0084\u0005r\u0000\u0000\u0084\u0085\u0005e\u0000\u0000\u0085"+ - "\u0086\u0005t\u0000\u0000\u0086\u0087\u0005u\u0000\u0000\u0087\u0088\u0005"+ - "r\u0000\u0000\u0088\u0089\u0005n\u0000\u0000\u0089\u0014\u0001\u0000\u0000"+ - "\u0000\u008a\u008b\u0005=\u0000\u0000\u008b\u0016\u0001\u0000\u0000\u0000"+ - "\u008c\u008d\u0005[\u0000\u0000\u008d\u0018\u0001\u0000\u0000\u0000\u008e"+ - "\u008f\u0005]\u0000\u0000\u008f\u001a\u0001\u0000\u0000\u0000\u0090\u0091"+ - "\u0005*\u0000\u0000\u0091\u001c\u0001\u0000\u0000\u0000\u0092\u0093\u0005"+ - "/\u0000\u0000\u0093\u001e\u0001\u0000\u0000\u0000\u0094\u0095\u0005+\u0000"+ - "\u0000\u0095 \u0001\u0000\u0000\u0000\u0096\u0097\u0005-\u0000\u0000\u0097"+ - "\"\u0001\u0000\u0000\u0000\u0098\u0099\u0005<\u0000\u0000\u0099\u009a"+ - "\u0005<\u0000\u0000\u009a$\u0001\u0000\u0000\u0000\u009b\u009c\u0005>"+ - "\u0000\u0000\u009c\u009d\u0005>\u0000\u0000\u009d&\u0001\u0000\u0000\u0000"+ - "\u009e\u009f\u0005&\u0000\u0000\u009f(\u0001\u0000\u0000\u0000\u00a0\u00a1"+ - "\u0005|\u0000\u0000\u00a1*\u0001\u0000\u0000\u0000\u00a2\u00a3\u0005^"+ - "\u0000\u0000\u00a3,\u0001\u0000\u0000\u0000\u00a4\u00a5\u0005i\u0000\u0000"+ - "\u00a5\u00a6\u0005n\u0000\u0000\u00a6\u00a7\u0005t\u0000\u0000\u00a7."+ - "\u0001\u0000\u0000\u0000\u00a8\u00a9\u0005u\u0000\u0000\u00a9\u00aa\u0005"+ - "i\u0000\u0000\u00aa\u00ab\u0005n\u0000\u0000\u00ab\u00ac\u0005t\u0000"+ - "\u0000\u00ac0\u0001\u0000\u0000\u0000\u00ad\u00ae\u0005s\u0000\u0000\u00ae"+ - "\u00af\u0005i\u0000\u0000\u00af\u00b0\u0005n\u0000\u0000\u00b0\u00b1\u0005"+ - "t\u0000\u0000\u00b12\u0001\u0000\u0000\u0000\u00b2\u00b3\u0005s\u0000"+ - "\u0000\u00b3\u00b4\u0005u\u0000\u0000\u00b4\u00b5\u0005i\u0000\u0000\u00b5"+ - "\u00b6\u0005n\u0000\u0000\u00b6\u00b7\u0005t\u0000\u0000\u00b74\u0001"+ - "\u0000\u0000\u0000\u00b8\u00b9\u0005f\u0000\u0000\u00b9\u00ba\u0005l\u0000"+ - "\u0000\u00ba\u00bb\u0005t\u0000\u0000\u00bb6\u0001\u0000\u0000\u0000\u00bc"+ - "\u00bd\u0005c\u0000\u0000\u00bd\u00be\u0005p\u0000\u0000\u00be\u00bf\u0005"+ - "l\u0000\u0000\u00bf8\u0001\u0000\u0000\u0000\u00c0\u00c1\u0005p\u0000"+ - "\u0000\u00c1\u00c2\u0005i\u0000\u0000\u00c2\u00c3\u0005x\u0000\u0000\u00c3"+ - ":\u0001\u0000\u0000\u0000\u00c4\u00c5\u0005i\u0000\u0000\u00c5\u00c6\u0005"+ - "p\u0000\u0000\u00c6\u00c7\u0005v\u0000\u0000\u00c7\u00c8\u00054\u0000"+ - "\u0000\u00c8<\u0001\u0000\u0000\u0000\u00c9\u00ca\u0005i\u0000\u0000\u00ca"+ - "\u00cb\u0005p\u0000\u0000\u00cb\u00cc\u0005v\u0000\u0000\u00cc\u00cd\u0005"+ - "6\u0000\u0000\u00cd>\u0001\u0000\u0000\u0000\u00ce\u00cf\u0005[\u0000"+ - "\u0000\u00cf\u00d0\u0005]\u0000\u0000\u00d0@\u0001\u0000\u0000\u0000\u00d1"+ - "\u00d2\u0005=\u0000\u0000\u00d2\u00d3\u0005=\u0000\u0000\u00d3B\u0001"+ - "\u0000\u0000\u0000\u00d4\u00d5\u0005!\u0000\u0000\u00d5\u00d6\u0005=\u0000"+ - "\u0000\u00d6D\u0001\u0000\u0000\u0000\u00d7\u00d8\u0005<\u0000\u0000\u00d8"+ - "F\u0001\u0000\u0000\u0000\u00d9\u00da\u0005>\u0000\u0000\u00daH\u0001"+ - "\u0000\u0000\u0000\u00db\u00dc\u0005<\u0000\u0000\u00dc\u00dd\u0005=\u0000"+ - "\u0000\u00ddJ\u0001\u0000\u0000\u0000\u00de\u00df\u0005>\u0000\u0000\u00df"+ - "\u00e0\u0005=\u0000\u0000\u00e0L\u0001\u0000\u0000\u0000\u00e1\u00e3\u0003"+ - "S)\u0000\u00e2\u00e4\u0003O\'\u0000\u00e3\u00e2\u0001\u0000\u0000\u0000"+ - "\u00e3\u00e4\u0001\u0000\u0000\u0000\u00e4\u00e6\u0001\u0000\u0000\u0000"+ - "\u00e5\u00e7\u0003Q(\u0000\u00e6\u00e5\u0001\u0000\u0000\u0000\u00e6\u00e7"+ - "\u0001\u0000\u0000\u0000\u00e7N\u0001\u0000\u0000\u0000\u00e8\u00ea\u0005"+ - "e\u0000\u0000\u00e9\u00eb\u0003_/\u0000\u00ea\u00e9\u0001\u0000\u0000"+ - "\u0000\u00ea\u00eb\u0001\u0000\u0000\u0000\u00eb\u00ec\u0001\u0000\u0000"+ - "\u0000\u00ec\u00f3\u0003Y,\u0000\u00ed\u00ef\u0005E\u0000\u0000\u00ee"+ - "\u00f0\u0003_/\u0000\u00ef\u00ee\u0001\u0000\u0000\u0000\u00ef\u00f0\u0001"+ - "\u0000\u0000\u0000\u00f0\u00f1\u0001\u0000\u0000\u0000\u00f1\u00f3\u0003"+ - "Y,\u0000\u00f2\u00e8\u0001\u0000\u0000\u0000\u00f2\u00ed\u0001\u0000\u0000"+ - "\u0000\u00f3P\u0001\u0000\u0000\u0000\u00f4\u00f5\u0007\u0000\u0000\u0000"+ - "\u00f5R\u0001\u0000\u0000\u0000\u00f6\u00f8\u0003Y,\u0000\u00f7\u00f6"+ - "\u0001\u0000\u0000\u0000\u00f7\u00f8\u0001\u0000\u0000\u0000\u00f8\u00f9"+ - "\u0001\u0000\u0000\u0000\u00f9\u00fa\u0005.\u0000\u0000\u00fa\u00ff\u0003"+ - "Y,\u0000\u00fb\u00fc\u0003Y,\u0000\u00fc\u00fd\u0005.\u0000\u0000\u00fd"+ - "\u00ff\u0001\u0000\u0000\u0000\u00fe\u00f7\u0001\u0000\u0000\u0000\u00fe"+ - "\u00fb\u0001\u0000\u0000\u0000\u00ffT\u0001\u0000\u0000\u0000\u0100\u0101"+ - "\u0003Y,\u0000\u0101V\u0001\u0000\u0000\u0000\u0102\u0106\u0003].\u0000"+ - "\u0103\u0105\u0003[-\u0000\u0104\u0103\u0001\u0000\u0000\u0000\u0105\u0108"+ - "\u0001\u0000\u0000\u0000\u0106\u0104\u0001\u0000\u0000\u0000\u0106\u0107"+ - "\u0001\u0000\u0000\u0000\u0107X\u0001\u0000\u0000\u0000\u0108\u0106\u0001"+ - "\u0000\u0000\u0000\u0109\u010b\u0003[-\u0000\u010a\u0109\u0001\u0000\u0000"+ - "\u0000\u010b\u010c\u0001\u0000\u0000\u0000\u010c\u010a\u0001\u0000\u0000"+ - "\u0000\u010c\u010d\u0001\u0000\u0000\u0000\u010dZ\u0001\u0000\u0000\u0000"+ - "\u010e\u010f\u0007\u0001\u0000\u0000\u010f\\\u0001\u0000\u0000\u0000\u0110"+ - "\u0111\u0007\u0002\u0000\u0000\u0111^\u0001\u0000\u0000\u0000\u0112\u0113"+ - "\u0007\u0003\u0000\u0000\u0113`\u0001\u0000\u0000\u0000\u0114\u0118\u0007"+ - "\u0004\u0000\u0000\u0115\u0117\u0007\u0005\u0000\u0000\u0116\u0115\u0001"+ - "\u0000\u0000\u0000\u0117\u011a\u0001\u0000\u0000\u0000\u0118\u0116\u0001"+ - "\u0000\u0000\u0000\u0118\u0119\u0001\u0000\u0000\u0000\u0119b\u0001\u0000"+ - "\u0000\u0000\u011a\u0118\u0001\u0000\u0000\u0000\u011b\u011c\u0005#\u0000"+ - "\u0000\u011c\u011d\u0005(\u0000\u0000\u011d\u011f\u0001\u0000\u0000\u0000"+ - "\u011e\u0120\b\u0006\u0000\u0000\u011f\u011e\u0001\u0000\u0000\u0000\u0120"+ - "\u0121\u0001\u0000\u0000\u0000\u0121\u011f\u0001\u0000\u0000\u0000\u0121"+ - "\u0122\u0001\u0000\u0000\u0000\u0122\u0123\u0001\u0000\u0000\u0000\u0123"+ - "\u0124\u0005)\u0000\u0000\u0124d\u0001\u0000\u0000\u0000\u0125\u0127\u0007"+ - "\u0007\u0000\u0000\u0126\u0125\u0001\u0000\u0000\u0000\u0127\u0128\u0001"+ - "\u0000\u0000\u0000\u0128\u0126\u0001\u0000\u0000\u0000\u0128\u0129\u0001"+ - "\u0000\u0000\u0000\u0129\u012a\u0001\u0000\u0000\u0000\u012a\u012b\u0006"+ - "2\u0000\u0000\u012bf\u0001\u0000\u0000\u0000\u012c\u012d\u0005/\u0000"+ - "\u0000\u012d\u012e\u0005/\u0000\u0000\u012e\u0132\u0001\u0000\u0000\u0000"+ - "\u012f\u0131\t\u0000\u0000\u0000\u0130\u012f\u0001\u0000\u0000\u0000\u0131"+ - "\u0134\u0001\u0000\u0000\u0000\u0132\u0133\u0001\u0000\u0000\u0000\u0132"+ - "\u0130\u0001\u0000\u0000\u0000\u0133\u0135\u0001\u0000\u0000\u0000\u0134"+ - "\u0132\u0001\u0000\u0000\u0000\u0135\u0136\u0003i4\u0000\u0136\u0137\u0001"+ - "\u0000\u0000\u0000\u0137\u0138\u00063\u0000\u0000\u0138h\u0001\u0000\u0000"+ - "\u0000\u0139\u013b\u0005\r\u0000\u0000\u013a\u0139\u0001\u0000\u0000\u0000"+ - "\u013a\u013b\u0001\u0000\u0000\u0000\u013b\u013c\u0001\u0000\u0000\u0000"+ - "\u013c\u013d\u0005\n\u0000\u0000\u013d\u013e\u0001\u0000\u0000\u0000\u013e"+ - "\u013f\u00064\u0000\u0000\u013fj\u0001\u0000\u0000\u0000\u000f\u0000\u00e3"+ - "\u00e6\u00ea\u00ef\u00f2\u00f7\u00fe\u0106\u010c\u0118\u0121\u0128\u0132"+ - "\u013a\u0001\u0006\u0000\u0000"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangLexer.tokens b/HybroLang/.antlr/HybroLangLexer.tokens deleted file mode 100644 index 574a34a..0000000 --- a/HybroLang/.antlr/HybroLangLexer.tokens +++ /dev/null @@ -1,84 +0,0 @@ -T__0=1 -T__1=2 -T__2=3 -T__3=4 -T__4=5 -T__5=6 -T__6=7 -T__7=8 -T__8=9 -T__9=10 -T__10=11 -T__11=12 -T__12=13 -T__13=14 -T__14=15 -T__15=16 -T__16=17 -T__17=18 -T__18=19 -T__19=20 -T__20=21 -T__21=22 -T__22=23 -T__23=24 -T__24=25 -T__25=26 -T__26=27 -T__27=28 -T__28=29 -T__29=30 -T__30=31 -T__31=32 -T__32=33 -T__33=34 -T__34=35 -T__35=36 -T__36=37 -T__37=38 -DecimalFloatingConstant=39 -IntegerConstant=40 -DecimalConstant=41 -Name=42 -INLINE=43 -WhiteSpace=44 -LineComment=45 -NewLine=46 -'('=1 -')'=2 -'{'=3 -'}'=4 -','=5 -';'=6 -'for'=7 -'if'=8 -'else'=9 -'return'=10 -'='=11 -'['=12 -']'=13 -'*'=14 -'/'=15 -'+'=16 -'-'=17 -'<<'=18 -'>>'=19 -'&'=20 -'|'=21 -'^'=22 -'int'=23 -'uint'=24 -'sint'=25 -'suint'=26 -'flt'=27 -'cpl'=28 -'pix'=29 -'ipv4'=30 -'ipv6'=31 -'[]'=32 -'=='=33 -'!='=34 -'<'=35 -'>'=36 -'<='=37 -'>='=38 diff --git a/HybroLang/.antlr/HybroLangListener.java b/HybroLang/.antlr/HybroLangListener.java deleted file mode 100644 index 17c0a14..0000000 --- a/HybroLang/.antlr/HybroLangListener.java +++ /dev/null @@ -1,255 +0,0 @@ -// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 -import org.antlr.v4.runtime.tree.ParseTreeListener; - -/** - * This interface defines a complete listener for a parse tree produced by - * {@link HybroLangParser}. - */ -public interface HybroLangListener extends ParseTreeListener { - /** - * Enter a parse tree produced by {@link HybroLangParser#compilationunit}. - * @param ctx the parse tree - */ - void enterCompilationunit(HybroLangParser.CompilationunitContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#compilationunit}. - * @param ctx the parse tree - */ - void exitCompilationunit(HybroLangParser.CompilationunitContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#function}. - * @param ctx the parse tree - */ - void enterFunction(HybroLangParser.FunctionContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#function}. - * @param ctx the parse tree - */ - void exitFunction(HybroLangParser.FunctionContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#fndcl}. - * @param ctx the parse tree - */ - void enterFndcl(HybroLangParser.FndclContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#fndcl}. - * @param ctx the parse tree - */ - void exitFndcl(HybroLangParser.FndclContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#fnprototype}. - * @param ctx the parse tree - */ - void enterFnprototype(HybroLangParser.FnprototypeContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#fnprototype}. - * @param ctx the parse tree - */ - void exitFnprototype(HybroLangParser.FnprototypeContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#fnbody}. - * @param ctx the parse tree - */ - void enterFnbody(HybroLangParser.FnbodyContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#fnbody}. - * @param ctx the parse tree - */ - void exitFnbody(HybroLangParser.FnbodyContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#paramdcllist}. - * @param ctx the parse tree - */ - void enterParamdcllist(HybroLangParser.ParamdcllistContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#paramdcllist}. - * @param ctx the parse tree - */ - void exitParamdcllist(HybroLangParser.ParamdcllistContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#localvardef}. - * @param ctx the parse tree - */ - void enterLocalvardef(HybroLangParser.LocalvardefContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#localvardef}. - * @param ctx the parse tree - */ - void exitLocalvardef(HybroLangParser.LocalvardefContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#vardcllist}. - * @param ctx the parse tree - */ - void enterVardcllist(HybroLangParser.VardcllistContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#vardcllist}. - * @param ctx the parse tree - */ - void exitVardcllist(HybroLangParser.VardcllistContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#vardcl}. - * @param ctx the parse tree - */ - void enterVardcl(HybroLangParser.VardclContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#vardcl}. - * @param ctx the parse tree - */ - void exitVardcl(HybroLangParser.VardclContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#actionlist}. - * @param ctx the parse tree - */ - void enterActionlist(HybroLangParser.ActionlistContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#actionlist}. - * @param ctx the parse tree - */ - void exitActionlist(HybroLangParser.ActionlistContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#condexpr}. - * @param ctx the parse tree - */ - void enterCondexpr(HybroLangParser.CondexprContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#condexpr}. - * @param ctx the parse tree - */ - void exitCondexpr(HybroLangParser.CondexprContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#action}. - * @param ctx the parse tree - */ - void enterAction(HybroLangParser.ActionContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#action}. - * @param ctx the parse tree - */ - void exitAction(HybroLangParser.ActionContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#returnexpr}. - * @param ctx the parse tree - */ - void enterReturnexpr(HybroLangParser.ReturnexprContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#returnexpr}. - * @param ctx the parse tree - */ - void exitReturnexpr(HybroLangParser.ReturnexprContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#affectexpr}. - * @param ctx the parse tree - */ - void enterAffectexpr(HybroLangParser.AffectexprContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#affectexpr}. - * @param ctx the parse tree - */ - void exitAffectexpr(HybroLangParser.AffectexprContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#unaryexpr}. - * @param ctx the parse tree - */ - void enterUnaryexpr(HybroLangParser.UnaryexprContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#unaryexpr}. - * @param ctx the parse tree - */ - void exitUnaryexpr(HybroLangParser.UnaryexprContext ctx); - /** - * Enter a parse tree produced by the {@code varorvalueArray} - * labeled alternative in {@link HybroLangParser#varorvalue}. - * @param ctx the parse tree - */ - void enterVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx); - /** - * Exit a parse tree produced by the {@code varorvalueArray} - * labeled alternative in {@link HybroLangParser#varorvalue}. - * @param ctx the parse tree - */ - void exitVarorvalueArray(HybroLangParser.VarorvalueArrayContext ctx); - /** - * Enter a parse tree produced by the {@code varorvalueConst} - * labeled alternative in {@link HybroLangParser#varorvalue}. - * @param ctx the parse tree - */ - void enterVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx); - /** - * Exit a parse tree produced by the {@code varorvalueConst} - * labeled alternative in {@link HybroLangParser#varorvalue}. - * @param ctx the parse tree - */ - void exitVarorvalueConst(HybroLangParser.VarorvalueConstContext ctx); - /** - * Enter a parse tree produced by the {@code varorvalueVar} - * labeled alternative in {@link HybroLangParser#varorvalue}. - * @param ctx the parse tree - */ - void enterVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx); - /** - * Exit a parse tree produced by the {@code varorvalueVar} - * labeled alternative in {@link HybroLangParser#varorvalue}. - * @param ctx the parse tree - */ - void exitVarorvalueVar(HybroLangParser.VarorvalueVarContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#datatype}. - * @param ctx the parse tree - */ - void enterDatatype(HybroLangParser.DatatypeContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#datatype}. - * @param ctx the parse tree - */ - void exitDatatype(HybroLangParser.DatatypeContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#intconstvalue}. - * @param ctx the parse tree - */ - void enterIntconstvalue(HybroLangParser.IntconstvalueContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#intconstvalue}. - * @param ctx the parse tree - */ - void exitIntconstvalue(HybroLangParser.IntconstvalueContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#constvalue}. - * @param ctx the parse tree - */ - void enterConstvalue(HybroLangParser.ConstvalueContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#constvalue}. - * @param ctx the parse tree - */ - void exitConstvalue(HybroLangParser.ConstvalueContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#constinline}. - * @param ctx the parse tree - */ - void enterConstinline(HybroLangParser.ConstinlineContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#constinline}. - * @param ctx the parse tree - */ - void exitConstinline(HybroLangParser.ConstinlineContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#typebase}. - * @param ctx the parse tree - */ - void enterTypebase(HybroLangParser.TypebaseContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#typebase}. - * @param ctx the parse tree - */ - void exitTypebase(HybroLangParser.TypebaseContext ctx); - /** - * Enter a parse tree produced by {@link HybroLangParser#condOperator}. - * @param ctx the parse tree - */ - void enterCondOperator(HybroLangParser.CondOperatorContext ctx); - /** - * Exit a parse tree produced by {@link HybroLangParser#condOperator}. - * @param ctx the parse tree - */ - void exitCondOperator(HybroLangParser.CondOperatorContext ctx); -} \ No newline at end of file diff --git a/HybroLang/.antlr/HybroLangParser.java b/HybroLang/.antlr/HybroLangParser.java deleted file mode 100644 index 784d4f0..0000000 --- a/HybroLang/.antlr/HybroLangParser.java +++ /dev/null @@ -1,1680 +0,0 @@ -// Generated from /homelocal/qm280442/HybroGen/HybroLang/HybroLang.g4 by ANTLR 4.13.1 -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.misc.*; -import org.antlr.v4.runtime.tree.*; -import java.util.List; -import java.util.Iterator; -import java.util.ArrayList; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) -public class HybroLangParser extends Parser { - static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, - T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, - T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24, - T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31, - T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38, - DecimalFloatingConstant=39, IntegerConstant=40, DecimalConstant=41, Name=42, - INLINE=43, WhiteSpace=44, LineComment=45, NewLine=46; - public static final int - RULE_compilationunit = 0, RULE_function = 1, RULE_fndcl = 2, RULE_fnprototype = 3, - RULE_fnbody = 4, RULE_paramdcllist = 5, RULE_localvardef = 6, RULE_vardcllist = 7, - RULE_vardcl = 8, RULE_actionlist = 9, RULE_condexpr = 10, RULE_action = 11, - RULE_returnexpr = 12, RULE_affectexpr = 13, RULE_unaryexpr = 14, RULE_varorvalue = 15, - RULE_datatype = 16, RULE_intconstvalue = 17, RULE_constvalue = 18, RULE_constinline = 19, - RULE_typebase = 20, RULE_condOperator = 21; - private static String[] makeRuleNames() { - return new String[] { - "compilationunit", "function", "fndcl", "fnprototype", "fnbody", "paramdcllist", - "localvardef", "vardcllist", "vardcl", "actionlist", "condexpr", "action", - "returnexpr", "affectexpr", "unaryexpr", "varorvalue", "datatype", "intconstvalue", - "constvalue", "constinline", "typebase", "condOperator" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, "'('", "')'", "'{'", "'}'", "','", "';'", "'for'", "'if'", "'else'", - "'return'", "'='", "'['", "']'", "'*'", "'/'", "'+'", "'-'", "'<<'", - "'>>'", "'&'", "'|'", "'^'", "'int'", "'uint'", "'sint'", "'suint'", - "'flt'", "'cpl'", "'pix'", "'ipv4'", "'ipv6'", "'[]'", "'=='", "'!='", - "'<'", "'>'", "'<='", "'>='" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, "DecimalFloatingConstant", "IntegerConstant", "DecimalConstant", - "Name", "INLINE", "WhiteSpace", "LineComment", "NewLine" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - @Override - public String getGrammarFileName() { return "HybroLang.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public ATN getATN() { return _ATN; } - - public HybroLangParser(TokenStream input) { - super(input); - _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @SuppressWarnings("CheckReturnValue") - public static class CompilationunitContext extends ParserRuleContext { - public List function() { - return getRuleContexts(FunctionContext.class); - } - public FunctionContext function(int i) { - return getRuleContext(FunctionContext.class,i); - } - public CompilationunitContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_compilationunit; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterCompilationunit(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitCompilationunit(this); - } - } - - public final CompilationunitContext compilationunit() throws RecognitionException { - CompilationunitContext _localctx = new CompilationunitContext(_ctx, getState()); - enterRule(_localctx, 0, RULE_compilationunit); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(45); - _errHandler.sync(this); - _la = _input.LA(1); - do { - { - { - setState(44); - function(); - } - } - setState(47); - _errHandler.sync(this); - _la = _input.LA(1); - } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & 4286578688L) != 0) ); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class FunctionContext extends ParserRuleContext { - public FndclContext fndcl() { - return getRuleContext(FndclContext.class,0); - } - public FnbodyContext fnbody() { - return getRuleContext(FnbodyContext.class,0); - } - public FunctionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_function; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFunction(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFunction(this); - } - } - - public final FunctionContext function() throws RecognitionException { - FunctionContext _localctx = new FunctionContext(_ctx, getState()); - enterRule(_localctx, 2, RULE_function); - try { - enterOuterAlt(_localctx, 1); - { - setState(49); - fndcl(); - setState(50); - fnbody(); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class FndclContext extends ParserRuleContext { - public DatatypeContext datatype() { - return getRuleContext(DatatypeContext.class,0); - } - public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } - public FnprototypeContext fnprototype() { - return getRuleContext(FnprototypeContext.class,0); - } - public FndclContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_fndcl; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFndcl(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFndcl(this); - } - } - - public final FndclContext fndcl() throws RecognitionException { - FndclContext _localctx = new FndclContext(_ctx, getState()); - enterRule(_localctx, 4, RULE_fndcl); - try { - enterOuterAlt(_localctx, 1); - { - setState(52); - datatype(); - setState(53); - match(Name); - setState(54); - fnprototype(); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class FnprototypeContext extends ParserRuleContext { - public ParamdcllistContext paramdcllist() { - return getRuleContext(ParamdcllistContext.class,0); - } - public FnprototypeContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_fnprototype; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFnprototype(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFnprototype(this); - } - } - - public final FnprototypeContext fnprototype() throws RecognitionException { - FnprototypeContext _localctx = new FnprototypeContext(_ctx, getState()); - enterRule(_localctx, 6, RULE_fnprototype); - try { - enterOuterAlt(_localctx, 1); - { - setState(56); - match(T__0); - setState(57); - paramdcllist(); - setState(58); - match(T__1); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class FnbodyContext extends ParserRuleContext { - public ActionlistContext actionlist() { - return getRuleContext(ActionlistContext.class,0); - } - public List localvardef() { - return getRuleContexts(LocalvardefContext.class); - } - public LocalvardefContext localvardef(int i) { - return getRuleContext(LocalvardefContext.class,i); - } - public ReturnexprContext returnexpr() { - return getRuleContext(ReturnexprContext.class,0); - } - public FnbodyContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_fnbody; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterFnbody(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitFnbody(this); - } - } - - public final FnbodyContext fnbody() throws RecognitionException { - FnbodyContext _localctx = new FnbodyContext(_ctx, getState()); - enterRule(_localctx, 8, RULE_fnbody); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(60); - match(T__2); - setState(64); - _errHandler.sync(this); - _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 4286578688L) != 0)) { - { - { - setState(61); - localvardef(); - } - } - setState(66); - _errHandler.sync(this); - _la = _input.LA(1); - } - setState(67); - actionlist(); - setState(69); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==T__9) { - { - setState(68); - returnexpr(); - } - } - - setState(71); - match(T__3); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class ParamdcllistContext extends ParserRuleContext { - public List vardcl() { - return getRuleContexts(VardclContext.class); - } - public VardclContext vardcl(int i) { - return getRuleContext(VardclContext.class,i); - } - public ParamdcllistContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_paramdcllist; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterParamdcllist(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitParamdcllist(this); - } - } - - public final ParamdcllistContext paramdcllist() throws RecognitionException { - ParamdcllistContext _localctx = new ParamdcllistContext(_ctx, getState()); - enterRule(_localctx, 10, RULE_paramdcllist); - int _la; - try { - setState(82); - _errHandler.sync(this); - switch (_input.LA(1)) { - case T__22: - case T__23: - case T__24: - case T__25: - case T__26: - case T__27: - case T__28: - case T__29: - case T__30: - enterOuterAlt(_localctx, 1); - { - setState(73); - vardcl(); - setState(78); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==T__4) { - { - { - setState(74); - match(T__4); - setState(75); - vardcl(); - } - } - setState(80); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - break; - case T__1: - enterOuterAlt(_localctx, 2); - { - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class LocalvardefContext extends ParserRuleContext { - public VardcllistContext vardcllist() { - return getRuleContext(VardcllistContext.class,0); - } - public LocalvardefContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_localvardef; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterLocalvardef(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitLocalvardef(this); - } - } - - public final LocalvardefContext localvardef() throws RecognitionException { - LocalvardefContext _localctx = new LocalvardefContext(_ctx, getState()); - enterRule(_localctx, 12, RULE_localvardef); - try { - enterOuterAlt(_localctx, 1); - { - setState(84); - vardcllist(); - setState(85); - match(T__5); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class VardcllistContext extends ParserRuleContext { - public VardclContext vardcl() { - return getRuleContext(VardclContext.class,0); - } - public List Name() { return getTokens(HybroLangParser.Name); } - public TerminalNode Name(int i) { - return getToken(HybroLangParser.Name, i); - } - public VardcllistContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_vardcllist; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVardcllist(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVardcllist(this); - } - } - - public final VardcllistContext vardcllist() throws RecognitionException { - VardcllistContext _localctx = new VardcllistContext(_ctx, getState()); - enterRule(_localctx, 14, RULE_vardcllist); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(87); - vardcl(); - setState(92); - _errHandler.sync(this); - _la = _input.LA(1); - while (_la==T__4) { - { - { - setState(88); - match(T__4); - setState(89); - match(Name); - } - } - setState(94); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class VardclContext extends ParserRuleContext { - public DatatypeContext datatype() { - return getRuleContext(DatatypeContext.class,0); - } - public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } - public VardclContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_vardcl; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVardcl(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVardcl(this); - } - } - - public final VardclContext vardcl() throws RecognitionException { - VardclContext _localctx = new VardclContext(_ctx, getState()); - enterRule(_localctx, 16, RULE_vardcl); - try { - enterOuterAlt(_localctx, 1); - { - setState(95); - datatype(); - setState(96); - match(Name); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class ActionlistContext extends ParserRuleContext { - public List action() { - return getRuleContexts(ActionContext.class); - } - public ActionContext action(int i) { - return getRuleContext(ActionContext.class,i); - } - public ActionlistContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_actionlist; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterActionlist(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitActionlist(this); - } - } - - public final ActionlistContext actionlist() throws RecognitionException { - ActionlistContext _localctx = new ActionlistContext(_ctx, getState()); - enterRule(_localctx, 18, RULE_actionlist); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(101); - _errHandler.sync(this); - _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 4398046511488L) != 0)) { - { - { - setState(98); - action(); - } - } - setState(103); - _errHandler.sync(this); - _la = _input.LA(1); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class CondexprContext extends ParserRuleContext { - public List varorvalue() { - return getRuleContexts(VarorvalueContext.class); - } - public VarorvalueContext varorvalue(int i) { - return getRuleContext(VarorvalueContext.class,i); - } - public CondOperatorContext condOperator() { - return getRuleContext(CondOperatorContext.class,0); - } - public CondexprContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_condexpr; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterCondexpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitCondexpr(this); - } - } - - public final CondexprContext condexpr() throws RecognitionException { - CondexprContext _localctx = new CondexprContext(_ctx, getState()); - enterRule(_localctx, 20, RULE_condexpr); - try { - enterOuterAlt(_localctx, 1); - { - setState(104); - varorvalue(); - setState(105); - condOperator(); - setState(106); - varorvalue(); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class ActionContext extends ParserRuleContext { - public List affectexpr() { - return getRuleContexts(AffectexprContext.class); - } - public AffectexprContext affectexpr(int i) { - return getRuleContext(AffectexprContext.class,i); - } - public CondexprContext condexpr() { - return getRuleContext(CondexprContext.class,0); - } - public List actionlist() { - return getRuleContexts(ActionlistContext.class); - } - public ActionlistContext actionlist(int i) { - return getRuleContext(ActionlistContext.class,i); - } - public ActionContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_action; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterAction(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitAction(this); - } - } - - public final ActionContext action() throws RecognitionException { - ActionContext _localctx = new ActionContext(_ctx, getState()); - enterRule(_localctx, 22, RULE_action); - try { - setState(135); - _errHandler.sync(this); - switch (_input.LA(1)) { - case Name: - enterOuterAlt(_localctx, 1); - { - setState(108); - affectexpr(); - setState(109); - match(T__5); - } - break; - case T__6: - enterOuterAlt(_localctx, 2); - { - setState(111); - match(T__6); - setState(112); - match(T__0); - setState(113); - affectexpr(); - setState(114); - match(T__5); - setState(115); - condexpr(); - setState(116); - match(T__5); - setState(117); - affectexpr(); - setState(118); - match(T__1); - setState(119); - match(T__2); - setState(120); - actionlist(); - setState(121); - match(T__3); - } - break; - case T__7: - enterOuterAlt(_localctx, 3); - { - setState(123); - match(T__7); - setState(124); - match(T__0); - setState(125); - condexpr(); - setState(126); - match(T__1); - setState(127); - match(T__2); - setState(128); - actionlist(); - setState(129); - match(T__3); - setState(130); - match(T__8); - setState(131); - match(T__2); - setState(132); - actionlist(); - setState(133); - match(T__3); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class ReturnexprContext extends ParserRuleContext { - public UnaryexprContext unaryexpr() { - return getRuleContext(UnaryexprContext.class,0); - } - public ReturnexprContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_returnexpr; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterReturnexpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitReturnexpr(this); - } - } - - public final ReturnexprContext returnexpr() throws RecognitionException { - ReturnexprContext _localctx = new ReturnexprContext(_ctx, getState()); - enterRule(_localctx, 24, RULE_returnexpr); - try { - enterOuterAlt(_localctx, 1); - { - setState(137); - match(T__9); - setState(138); - unaryexpr(0); - setState(139); - match(T__5); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class AffectexprContext extends ParserRuleContext { - public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } - public List unaryexpr() { - return getRuleContexts(UnaryexprContext.class); - } - public UnaryexprContext unaryexpr(int i) { - return getRuleContext(UnaryexprContext.class,i); - } - public AffectexprContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_affectexpr; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterAffectexpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitAffectexpr(this); - } - } - - public final AffectexprContext affectexpr() throws RecognitionException { - AffectexprContext _localctx = new AffectexprContext(_ctx, getState()); - enterRule(_localctx, 26, RULE_affectexpr); - try { - setState(151); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) { - case 1: - enterOuterAlt(_localctx, 1); - { - setState(141); - match(Name); - setState(142); - match(T__10); - setState(143); - unaryexpr(0); - } - break; - case 2: - enterOuterAlt(_localctx, 2); - { - setState(144); - match(Name); - setState(145); - match(T__11); - setState(146); - unaryexpr(0); - setState(147); - match(T__12); - setState(148); - match(T__10); - setState(149); - unaryexpr(0); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class UnaryexprContext extends ParserRuleContext { - public Token op; - public VarorvalueContext varorvalue() { - return getRuleContext(VarorvalueContext.class,0); - } - public List unaryexpr() { - return getRuleContexts(UnaryexprContext.class); - } - public UnaryexprContext unaryexpr(int i) { - return getRuleContext(UnaryexprContext.class,i); - } - public UnaryexprContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_unaryexpr; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterUnaryexpr(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitUnaryexpr(this); - } - } - - public final UnaryexprContext unaryexpr() throws RecognitionException { - return unaryexpr(0); - } - - private UnaryexprContext unaryexpr(int _p) throws RecognitionException { - ParserRuleContext _parentctx = _ctx; - int _parentState = getState(); - UnaryexprContext _localctx = new UnaryexprContext(_ctx, _parentState); - UnaryexprContext _prevctx = _localctx; - int _startState = 28; - enterRecursionRule(_localctx, 28, RULE_unaryexpr, _p); - int _la; - try { - int _alt; - enterOuterAlt(_localctx, 1); - { - { - setState(154); - varorvalue(); - } - _ctx.stop = _input.LT(-1); - setState(170); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,10,_ctx); - while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { - if ( _alt==1 ) { - if ( _parseListeners!=null ) triggerExitRuleEvent(); - _prevctx = _localctx; - { - setState(168); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) { - case 1: - { - _localctx = new UnaryexprContext(_parentctx, _parentState); - pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); - setState(156); - if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); - setState(157); - ((UnaryexprContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==T__13 || _la==T__14) ) { - ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(158); - unaryexpr(6); - } - break; - case 2: - { - _localctx = new UnaryexprContext(_parentctx, _parentState); - pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); - setState(159); - if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); - setState(160); - ((UnaryexprContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==T__15 || _la==T__16) ) { - ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(161); - unaryexpr(5); - } - break; - case 3: - { - _localctx = new UnaryexprContext(_parentctx, _parentState); - pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); - setState(162); - if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(163); - ((UnaryexprContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !(_la==T__17 || _la==T__18) ) { - ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(164); - unaryexpr(4); - } - break; - case 4: - { - _localctx = new UnaryexprContext(_parentctx, _parentState); - pushNewRecursionContext(_localctx, _startState, RULE_unaryexpr); - setState(165); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(166); - ((UnaryexprContext)_localctx).op = _input.LT(1); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 7340032L) != 0)) ) { - ((UnaryexprContext)_localctx).op = (Token)_errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(167); - unaryexpr(3); - } - break; - } - } - } - setState(172); - _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,10,_ctx); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - unrollRecursionContexts(_parentctx); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class VarorvalueContext extends ParserRuleContext { - public VarorvalueContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_varorvalue; } - - public VarorvalueContext() { } - public void copyFrom(VarorvalueContext ctx) { - super.copyFrom(ctx); - } - } - @SuppressWarnings("CheckReturnValue") - public static class VarorvalueVarContext extends VarorvalueContext { - public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } - public VarorvalueVarContext(VarorvalueContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVarorvalueVar(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVarorvalueVar(this); - } - } - @SuppressWarnings("CheckReturnValue") - public static class VarorvalueArrayContext extends VarorvalueContext { - public TerminalNode Name() { return getToken(HybroLangParser.Name, 0); } - public UnaryexprContext unaryexpr() { - return getRuleContext(UnaryexprContext.class,0); - } - public VarorvalueArrayContext(VarorvalueContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVarorvalueArray(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVarorvalueArray(this); - } - } - @SuppressWarnings("CheckReturnValue") - public static class VarorvalueConstContext extends VarorvalueContext { - public ConstvalueContext constvalue() { - return getRuleContext(ConstvalueContext.class,0); - } - public VarorvalueConstContext(VarorvalueContext ctx) { copyFrom(ctx); } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterVarorvalueConst(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitVarorvalueConst(this); - } - } - - public final VarorvalueContext varorvalue() throws RecognitionException { - VarorvalueContext _localctx = new VarorvalueContext(_ctx, getState()); - enterRule(_localctx, 30, RULE_varorvalue); - try { - setState(180); - _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { - case 1: - _localctx = new VarorvalueArrayContext(_localctx); - enterOuterAlt(_localctx, 1); - { - setState(173); - match(Name); - setState(174); - match(T__11); - setState(175); - unaryexpr(0); - setState(176); - match(T__12); - } - break; - case 2: - _localctx = new VarorvalueConstContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(178); - constvalue(); - } - break; - case 3: - _localctx = new VarorvalueVarContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(179); - match(Name); - } - break; - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class DatatypeContext extends ParserRuleContext { - public IntconstvalueContext wordlen; - public IntconstvalueContext vectorlen; - public TypebaseContext typebase() { - return getRuleContext(TypebaseContext.class,0); - } - public List intconstvalue() { - return getRuleContexts(IntconstvalueContext.class); - } - public IntconstvalueContext intconstvalue(int i) { - return getRuleContext(IntconstvalueContext.class,i); - } - public DatatypeContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_datatype; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterDatatype(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitDatatype(this); - } - } - - public final DatatypeContext datatype() throws RecognitionException { - DatatypeContext _localctx = new DatatypeContext(_ctx, getState()); - enterRule(_localctx, 32, RULE_datatype); - try { - enterOuterAlt(_localctx, 1); - { - setState(182); - typebase(); - setState(183); - ((DatatypeContext)_localctx).wordlen = intconstvalue(); - setState(184); - ((DatatypeContext)_localctx).vectorlen = intconstvalue(); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class IntconstvalueContext extends ParserRuleContext { - public TerminalNode IntegerConstant() { return getToken(HybroLangParser.IntegerConstant, 0); } - public ConstinlineContext constinline() { - return getRuleContext(ConstinlineContext.class,0); - } - public IntconstvalueContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_intconstvalue; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterIntconstvalue(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitIntconstvalue(this); - } - } - - public final IntconstvalueContext intconstvalue() throws RecognitionException { - IntconstvalueContext _localctx = new IntconstvalueContext(_ctx, getState()); - enterRule(_localctx, 34, RULE_intconstvalue); - try { - setState(188); - _errHandler.sync(this); - switch (_input.LA(1)) { - case IntegerConstant: - enterOuterAlt(_localctx, 1); - { - setState(186); - match(IntegerConstant); - } - break; - case INLINE: - enterOuterAlt(_localctx, 2); - { - setState(187); - constinline(); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class ConstvalueContext extends ParserRuleContext { - public TerminalNode IntegerConstant() { return getToken(HybroLangParser.IntegerConstant, 0); } - public TerminalNode DecimalFloatingConstant() { return getToken(HybroLangParser.DecimalFloatingConstant, 0); } - public ConstinlineContext constinline() { - return getRuleContext(ConstinlineContext.class,0); - } - public ConstvalueContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_constvalue; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterConstvalue(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitConstvalue(this); - } - } - - public final ConstvalueContext constvalue() throws RecognitionException { - ConstvalueContext _localctx = new ConstvalueContext(_ctx, getState()); - enterRule(_localctx, 36, RULE_constvalue); - try { - setState(193); - _errHandler.sync(this); - switch (_input.LA(1)) { - case IntegerConstant: - enterOuterAlt(_localctx, 1); - { - setState(190); - match(IntegerConstant); - } - break; - case DecimalFloatingConstant: - enterOuterAlt(_localctx, 2); - { - setState(191); - match(DecimalFloatingConstant); - } - break; - case INLINE: - enterOuterAlt(_localctx, 3); - { - setState(192); - constinline(); - } - break; - default: - throw new NoViableAltException(this); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class ConstinlineContext extends ParserRuleContext { - public TerminalNode INLINE() { return getToken(HybroLangParser.INLINE, 0); } - public ConstinlineContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_constinline; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterConstinline(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitConstinline(this); - } - } - - public final ConstinlineContext constinline() throws RecognitionException { - ConstinlineContext _localctx = new ConstinlineContext(_ctx, getState()); - enterRule(_localctx, 38, RULE_constinline); - try { - enterOuterAlt(_localctx, 1); - { - setState(195); - match(INLINE); - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class TypebaseContext extends ParserRuleContext { - public TypebaseContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_typebase; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterTypebase(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitTypebase(this); - } - } - - public final TypebaseContext typebase() throws RecognitionException { - TypebaseContext _localctx = new TypebaseContext(_ctx, getState()); - enterRule(_localctx, 40, RULE_typebase); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(197); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 4286578688L) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(199); - _errHandler.sync(this); - _la = _input.LA(1); - if (_la==T__31) { - { - setState(198); - match(T__31); - } - } - - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - @SuppressWarnings("CheckReturnValue") - public static class CondOperatorContext extends ParserRuleContext { - public CondOperatorContext(ParserRuleContext parent, int invokingState) { - super(parent, invokingState); - } - @Override public int getRuleIndex() { return RULE_condOperator; } - @Override - public void enterRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).enterCondOperator(this); - } - @Override - public void exitRule(ParseTreeListener listener) { - if ( listener instanceof HybroLangListener ) ((HybroLangListener)listener).exitCondOperator(this); - } - } - - public final CondOperatorContext condOperator() throws RecognitionException { - CondOperatorContext _localctx = new CondOperatorContext(_ctx, getState()); - enterRule(_localctx, 42, RULE_condOperator); - int _la; - try { - enterOuterAlt(_localctx, 1); - { - setState(201); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 541165879296L) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - } - } - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } - finally { - exitRule(); - } - return _localctx; - } - - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 14: - return unaryexpr_sempred((UnaryexprContext)_localctx, predIndex); - } - return true; - } - private boolean unaryexpr_sempred(UnaryexprContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return precpred(_ctx, 5); - case 1: - return precpred(_ctx, 4); - case 2: - return precpred(_ctx, 3); - case 3: - return precpred(_ctx, 2); - } - return true; - } - - public static final String _serializedATN = - "\u0004\u0001.\u00cc\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ - "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+ - "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+ - "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+ - "\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007\u000f"+ - "\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007\u0012"+ - "\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007\u0015"+ - "\u0001\u0000\u0004\u0000.\b\u0000\u000b\u0000\f\u0000/\u0001\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+ - "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0005"+ - "\u0004?\b\u0004\n\u0004\f\u0004B\t\u0004\u0001\u0004\u0001\u0004\u0003"+ - "\u0004F\b\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001"+ - "\u0005\u0005\u0005M\b\u0005\n\u0005\f\u0005P\t\u0005\u0001\u0005\u0003"+ - "\u0005S\b\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0007\u0001"+ - "\u0007\u0001\u0007\u0005\u0007[\b\u0007\n\u0007\f\u0007^\t\u0007\u0001"+ - "\b\u0001\b\u0001\b\u0001\t\u0005\td\b\t\n\t\f\tg\t\t\u0001\n\u0001\n\u0001"+ - "\n\u0001\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+ - "\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0003\u000b\u0088\b\u000b"+ - "\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ - "\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0003\r\u0098\b\r\u0001\u000e"+ - "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ - "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e"+ - "\u0001\u000e\u0001\u000e\u0005\u000e\u00a9\b\u000e\n\u000e\f\u000e\u00ac"+ - "\t\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001"+ - "\u000f\u0001\u000f\u0003\u000f\u00b5\b\u000f\u0001\u0010\u0001\u0010\u0001"+ - "\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0003\u0011\u00bd\b\u0011\u0001"+ - "\u0012\u0001\u0012\u0001\u0012\u0003\u0012\u00c2\b\u0012\u0001\u0013\u0001"+ - "\u0013\u0001\u0014\u0001\u0014\u0003\u0014\u00c8\b\u0014\u0001\u0015\u0001"+ - "\u0015\u0001\u0015\u0000\u0001\u001c\u0016\u0000\u0002\u0004\u0006\b\n"+ - "\f\u000e\u0010\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*\u0000"+ - "\u0006\u0001\u0000\u000e\u000f\u0001\u0000\u0010\u0011\u0001\u0000\u0012"+ - "\u0013\u0001\u0000\u0014\u0016\u0001\u0000\u0017\u001f\u0001\u0000!&\u00c9"+ - "\u0000-\u0001\u0000\u0000\u0000\u00021\u0001\u0000\u0000\u0000\u00044"+ - "\u0001\u0000\u0000\u0000\u00068\u0001\u0000\u0000\u0000\b<\u0001\u0000"+ - "\u0000\u0000\nR\u0001\u0000\u0000\u0000\fT\u0001\u0000\u0000\u0000\u000e"+ - "W\u0001\u0000\u0000\u0000\u0010_\u0001\u0000\u0000\u0000\u0012e\u0001"+ - "\u0000\u0000\u0000\u0014h\u0001\u0000\u0000\u0000\u0016\u0087\u0001\u0000"+ - "\u0000\u0000\u0018\u0089\u0001\u0000\u0000\u0000\u001a\u0097\u0001\u0000"+ - "\u0000\u0000\u001c\u0099\u0001\u0000\u0000\u0000\u001e\u00b4\u0001\u0000"+ - "\u0000\u0000 \u00b6\u0001\u0000\u0000\u0000\"\u00bc\u0001\u0000\u0000"+ - "\u0000$\u00c1\u0001\u0000\u0000\u0000&\u00c3\u0001\u0000\u0000\u0000("+ - "\u00c5\u0001\u0000\u0000\u0000*\u00c9\u0001\u0000\u0000\u0000,.\u0003"+ - "\u0002\u0001\u0000-,\u0001\u0000\u0000\u0000./\u0001\u0000\u0000\u0000"+ - "/-\u0001\u0000\u0000\u0000/0\u0001\u0000\u0000\u00000\u0001\u0001\u0000"+ - "\u0000\u000012\u0003\u0004\u0002\u000023\u0003\b\u0004\u00003\u0003\u0001"+ - "\u0000\u0000\u000045\u0003 \u0010\u000056\u0005*\u0000\u000067\u0003\u0006"+ - "\u0003\u00007\u0005\u0001\u0000\u0000\u000089\u0005\u0001\u0000\u0000"+ - "9:\u0003\n\u0005\u0000:;\u0005\u0002\u0000\u0000;\u0007\u0001\u0000\u0000"+ - "\u0000<@\u0005\u0003\u0000\u0000=?\u0003\f\u0006\u0000>=\u0001\u0000\u0000"+ - "\u0000?B\u0001\u0000\u0000\u0000@>\u0001\u0000\u0000\u0000@A\u0001\u0000"+ - "\u0000\u0000AC\u0001\u0000\u0000\u0000B@\u0001\u0000\u0000\u0000CE\u0003"+ - "\u0012\t\u0000DF\u0003\u0018\f\u0000ED\u0001\u0000\u0000\u0000EF\u0001"+ - "\u0000\u0000\u0000FG\u0001\u0000\u0000\u0000GH\u0005\u0004\u0000\u0000"+ - "H\t\u0001\u0000\u0000\u0000IN\u0003\u0010\b\u0000JK\u0005\u0005\u0000"+ - "\u0000KM\u0003\u0010\b\u0000LJ\u0001\u0000\u0000\u0000MP\u0001\u0000\u0000"+ - "\u0000NL\u0001\u0000\u0000\u0000NO\u0001\u0000\u0000\u0000OS\u0001\u0000"+ - "\u0000\u0000PN\u0001\u0000\u0000\u0000QS\u0001\u0000\u0000\u0000RI\u0001"+ - "\u0000\u0000\u0000RQ\u0001\u0000\u0000\u0000S\u000b\u0001\u0000\u0000"+ - "\u0000TU\u0003\u000e\u0007\u0000UV\u0005\u0006\u0000\u0000V\r\u0001\u0000"+ - "\u0000\u0000W\\\u0003\u0010\b\u0000XY\u0005\u0005\u0000\u0000Y[\u0005"+ - "*\u0000\u0000ZX\u0001\u0000\u0000\u0000[^\u0001\u0000\u0000\u0000\\Z\u0001"+ - "\u0000\u0000\u0000\\]\u0001\u0000\u0000\u0000]\u000f\u0001\u0000\u0000"+ - "\u0000^\\\u0001\u0000\u0000\u0000_`\u0003 \u0010\u0000`a\u0005*\u0000"+ - "\u0000a\u0011\u0001\u0000\u0000\u0000bd\u0003\u0016\u000b\u0000cb\u0001"+ - "\u0000\u0000\u0000dg\u0001\u0000\u0000\u0000ec\u0001\u0000\u0000\u0000"+ - "ef\u0001\u0000\u0000\u0000f\u0013\u0001\u0000\u0000\u0000ge\u0001\u0000"+ - "\u0000\u0000hi\u0003\u001e\u000f\u0000ij\u0003*\u0015\u0000jk\u0003\u001e"+ - "\u000f\u0000k\u0015\u0001\u0000\u0000\u0000lm\u0003\u001a\r\u0000mn\u0005"+ - "\u0006\u0000\u0000n\u0088\u0001\u0000\u0000\u0000op\u0005\u0007\u0000"+ - "\u0000pq\u0005\u0001\u0000\u0000qr\u0003\u001a\r\u0000rs\u0005\u0006\u0000"+ - "\u0000st\u0003\u0014\n\u0000tu\u0005\u0006\u0000\u0000uv\u0003\u001a\r"+ - "\u0000vw\u0005\u0002\u0000\u0000wx\u0005\u0003\u0000\u0000xy\u0003\u0012"+ - "\t\u0000yz\u0005\u0004\u0000\u0000z\u0088\u0001\u0000\u0000\u0000{|\u0005"+ - "\b\u0000\u0000|}\u0005\u0001\u0000\u0000}~\u0003\u0014\n\u0000~\u007f"+ - "\u0005\u0002\u0000\u0000\u007f\u0080\u0005\u0003\u0000\u0000\u0080\u0081"+ - "\u0003\u0012\t\u0000\u0081\u0082\u0005\u0004\u0000\u0000\u0082\u0083\u0005"+ - "\t\u0000\u0000\u0083\u0084\u0005\u0003\u0000\u0000\u0084\u0085\u0003\u0012"+ - "\t\u0000\u0085\u0086\u0005\u0004\u0000\u0000\u0086\u0088\u0001\u0000\u0000"+ - "\u0000\u0087l\u0001\u0000\u0000\u0000\u0087o\u0001\u0000\u0000\u0000\u0087"+ - "{\u0001\u0000\u0000\u0000\u0088\u0017\u0001\u0000\u0000\u0000\u0089\u008a"+ - "\u0005\n\u0000\u0000\u008a\u008b\u0003\u001c\u000e\u0000\u008b\u008c\u0005"+ - "\u0006\u0000\u0000\u008c\u0019\u0001\u0000\u0000\u0000\u008d\u008e\u0005"+ - "*\u0000\u0000\u008e\u008f\u0005\u000b\u0000\u0000\u008f\u0098\u0003\u001c"+ - "\u000e\u0000\u0090\u0091\u0005*\u0000\u0000\u0091\u0092\u0005\f\u0000"+ - "\u0000\u0092\u0093\u0003\u001c\u000e\u0000\u0093\u0094\u0005\r\u0000\u0000"+ - "\u0094\u0095\u0005\u000b\u0000\u0000\u0095\u0096\u0003\u001c\u000e\u0000"+ - "\u0096\u0098\u0001\u0000\u0000\u0000\u0097\u008d\u0001\u0000\u0000\u0000"+ - "\u0097\u0090\u0001\u0000\u0000\u0000\u0098\u001b\u0001\u0000\u0000\u0000"+ - "\u0099\u009a\u0006\u000e\uffff\uffff\u0000\u009a\u009b\u0003\u001e\u000f"+ - "\u0000\u009b\u00aa\u0001\u0000\u0000\u0000\u009c\u009d\n\u0005\u0000\u0000"+ - "\u009d\u009e\u0007\u0000\u0000\u0000\u009e\u00a9\u0003\u001c\u000e\u0006"+ - "\u009f\u00a0\n\u0004\u0000\u0000\u00a0\u00a1\u0007\u0001\u0000\u0000\u00a1"+ - "\u00a9\u0003\u001c\u000e\u0005\u00a2\u00a3\n\u0003\u0000\u0000\u00a3\u00a4"+ - "\u0007\u0002\u0000\u0000\u00a4\u00a9\u0003\u001c\u000e\u0004\u00a5\u00a6"+ - "\n\u0002\u0000\u0000\u00a6\u00a7\u0007\u0003\u0000\u0000\u00a7\u00a9\u0003"+ - "\u001c\u000e\u0003\u00a8\u009c\u0001\u0000\u0000\u0000\u00a8\u009f\u0001"+ - "\u0000\u0000\u0000\u00a8\u00a2\u0001\u0000\u0000\u0000\u00a8\u00a5\u0001"+ - "\u0000\u0000\u0000\u00a9\u00ac\u0001\u0000\u0000\u0000\u00aa\u00a8\u0001"+ - "\u0000\u0000\u0000\u00aa\u00ab\u0001\u0000\u0000\u0000\u00ab\u001d\u0001"+ - "\u0000\u0000\u0000\u00ac\u00aa\u0001\u0000\u0000\u0000\u00ad\u00ae\u0005"+ - "*\u0000\u0000\u00ae\u00af\u0005\f\u0000\u0000\u00af\u00b0\u0003\u001c"+ - "\u000e\u0000\u00b0\u00b1\u0005\r\u0000\u0000\u00b1\u00b5\u0001\u0000\u0000"+ - "\u0000\u00b2\u00b5\u0003$\u0012\u0000\u00b3\u00b5\u0005*\u0000\u0000\u00b4"+ - "\u00ad\u0001\u0000\u0000\u0000\u00b4\u00b2\u0001\u0000\u0000\u0000\u00b4"+ - "\u00b3\u0001\u0000\u0000\u0000\u00b5\u001f\u0001\u0000\u0000\u0000\u00b6"+ - "\u00b7\u0003(\u0014\u0000\u00b7\u00b8\u0003\"\u0011\u0000\u00b8\u00b9"+ - "\u0003\"\u0011\u0000\u00b9!\u0001\u0000\u0000\u0000\u00ba\u00bd\u0005"+ - "(\u0000\u0000\u00bb\u00bd\u0003&\u0013\u0000\u00bc\u00ba\u0001\u0000\u0000"+ - "\u0000\u00bc\u00bb\u0001\u0000\u0000\u0000\u00bd#\u0001\u0000\u0000\u0000"+ - "\u00be\u00c2\u0005(\u0000\u0000\u00bf\u00c2\u0005\'\u0000\u0000\u00c0"+ - "\u00c2\u0003&\u0013\u0000\u00c1\u00be\u0001\u0000\u0000\u0000\u00c1\u00bf"+ - "\u0001\u0000\u0000\u0000\u00c1\u00c0\u0001\u0000\u0000\u0000\u00c2%\u0001"+ - "\u0000\u0000\u0000\u00c3\u00c4\u0005+\u0000\u0000\u00c4\'\u0001\u0000"+ - "\u0000\u0000\u00c5\u00c7\u0007\u0004\u0000\u0000\u00c6\u00c8\u0005 \u0000"+ - "\u0000\u00c7\u00c6\u0001\u0000\u0000\u0000\u00c7\u00c8\u0001\u0000\u0000"+ - "\u0000\u00c8)\u0001\u0000\u0000\u0000\u00c9\u00ca\u0007\u0005\u0000\u0000"+ - "\u00ca+\u0001\u0000\u0000\u0000\u000f/@ENR\\e\u0087\u0097\u00a8\u00aa"+ - "\u00b4\u00bc\u00c1\u00c7"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} \ No newline at end of file From ff03240358a351dd14309d66daa9feadc4a991e4 Mon Sep 17 00:00:00 2001 From: Quentin MELOTTE Date: Wed, 22 Jul 2026 15:53:50 +0200 Subject: [PATCH 5/6] Delete pycache --- __pycache__/H2Utils.cpython-312.pyc | Bin 394 -> 0 bytes __pycache__/SwConfig.cpython-312.pyc | Bin 2594 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __pycache__/H2Utils.cpython-312.pyc delete mode 100644 __pycache__/SwConfig.cpython-312.pyc diff --git a/__pycache__/H2Utils.cpython-312.pyc b/__pycache__/H2Utils.cpython-312.pyc deleted file mode 100644 index f69dbf9c4fa23244a66e9cc896233d520e53fbbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394 zcmX@j%ge<81Y74`&ny7ak3k$5V1hC}3jrC^8B!Qh7;_k+7*d#87@`;}88w+-f)w~A zGeXsYC>9`Q2I9|NKw>&W30y9Pv4)|Fje%h`RD_YC1f&iOvOv1fKnfE=WhH|qvtN~f zTVhFKjzVftQGStvm4a&V%l|;2$$X2opeQr1sS7?_wC>3dWr73I69=IMJFg_dOI6zdgK-r`CFS>OsXzX%j6 ztUz2W4I~;E?yzuP;Fg_He34uE3X94e7WQ_JMvso5R-ey6X$DQEBB0M0z?xPv6mf&t soIv6ihfQvNN@-52T@f#k3vx~|Kalvq%*e?2nT>&w`!fp@qaauV0N5o`r2qf` diff --git a/__pycache__/SwConfig.cpython-312.pyc b/__pycache__/SwConfig.cpython-312.pyc deleted file mode 100644 index 417185eb10329bd2afaff98cb6ffd6a30aae5eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2594 zcmb_eO>7fK6n?Wm_BwHJ0vJM2(WVJ5E+mGCpMZc6@&kfmiJvsoQduqDO>nTi$*fKA z)
QYfhqr%+W$9C`q8;Z$+u+>1>R3EN{&y(Od-RZe~5^%^HiXb+6!Z)WGcdGC8~ z-kapNy1E*`@#~}c#9k5L5BA{>e|fRIj{wX92WLQoDbUC>&XL4GCmMHi4*>n1109}~ z55zc~8}YhkKFk%lfZC!iJVU!|5VWm}8m|eK2jIi5F7(2;0{}5kNuL`DIQrG7dt7}@ z{8`jI=((Xhhl9cwAP~nmnebvSB%1I+>+vCSjya`Fb{y)Z~zyHT9CM zxJ!}IW*5ifZ`nqe#p~7}2@_lb@}QJ248R9@ZUhTv?Z{NFJx|=kxbp;`=kY?f0!#>b zArB+fUdx8^n2H^^K90YcZJ17IfsEvOX$2~i|MaYJd1B!a*RMNI@ZZ49>2bJ?^Ee3$ z(Lb48i*Ij_*pf=)H@-@knXqW{ar2ffvAmwfyxKLriFoFcu4+291!GiC+YSARq#iXg z{YEye^-*e2JSCWVa>(A~WV)oFrgX~EVSA`^noyIajNP8R(iyp7r1Yc_SCf&kR7dCj zg9kezXLHx7aYj!^dJIkPyRD{1le!r}g6`$FkLGMiQ4;AyMp3MW%C@`3{Fx@gB>XOI zUTAEZ7G~-eIo@}QECd^8uRXZ-OYf6ibFH0o!K2gtiyqkA_zsA#ZMu75@4o5Y`xowB zc-Z{#+)r(<{Ck#o6#Vm-2=&cOr`kgB$(>^O#9ZsixnS21{fnr0imaHd@qTRTCh(Gk zy1(RKh6!T4QZp!JH(shOrxmaUaAWNlVH#_O`*d7}Fo}ja%1Xi(Zt6KROelM(Oy)+W z^=#ietY^-n$f~d8r@X@$nyjZMVIi>P{>0sh`9O0q&^#AtDM&5LD1cSHP~p1|C9~K8 z>+#JKRa-GM3PW-T0K0NI&IDbe)2WVu_f{hg@d98F}^?sZp#i z+HcTqEJ|xpvxmB^TrnGP4wgBu&Zf0%E%nv%&o+qQPBCz}ARR765DgQ{ zUonI4ANzx&C~2%uMX_rXC1q&YBwPCxWh|>E%M!1mXhvL7C~GXrs*$p4q|7Ik8GMfL z6iQA?%}H5vmw+wI-3U{##Brju?2*K_cUy_r`p!edqYOG2M3xbbI2PC$Ml7W!()j*u z+1+u-l*_Q+S%n2#a=XO#mQ!K**p;^RVLe#>($W?1Cp!+U5ZS_ce>7a{&}(6CNZbhs z|0Mxi9HohL#wO}|@zF0(|rvWBj7Vh$a~LDa%2e*7LS48pSE7{ zJKjq5_i84)7XtP7b9Zz1zMDMzR`5-Cz81FPT&R@`%>%{Sf!D&<3w1$!iN*8WG=e-*u_jb*XUq%A2l%!r;~U!QtZIaN$Pc&EQBOnR*Y9BE8&_ iGc5x2asAxi?CT7NU-jqMhwnUxk3QO8tOcQ|6w$xBJU12q From ba9d3aa008f24b5070607728ea1ab1a87b207215 Mon Sep 17 00:00:00 2001 From: Quentin MELOTTE Date: Wed, 22 Jul 2026 15:55:03 +0200 Subject: [PATCH 6/6] Delete codeExample unecessary file --- .../__pycache__/CCode.cpython-312.pyc | Bin 10296 -> 0 bytes CodeExamples/regression-single-op-aarch64.csv | 2304 ----------------- 2 files changed, 2304 deletions(-) delete mode 100644 CodeExamples/__pycache__/CCode.cpython-312.pyc delete mode 100644 CodeExamples/regression-single-op-aarch64.csv diff --git a/CodeExamples/__pycache__/CCode.cpython-312.pyc b/CodeExamples/__pycache__/CCode.cpython-312.pyc deleted file mode 100644 index a4ada0eb4cac08daf96790a05e53526fcb720192..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10296 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 avwM;6p-uAqft0iH0l)Kc3&U4Z>HH@P-{=nj diff --git a/CodeExamples/regression-single-op-aarch64.csv b/CodeExamples/regression-single-op-aarch64.csv deleted file mode 100644 index 210b1d7..0000000 --- a/CodeExamples/regression-single-op-aarch64.csv +++ /dev/null @@ -1,2304 +0,0 @@ -add;int;8;1;value;aarch64;Success; -add;int;8;2;value;aarch64;Fail -add;int;8;4;value;aarch64;Fail -add;int;8;8;value;aarch64;Fail -add;int;8;16;value;aarch64;Fail -add;int;8;32;value;aarch64;Fail -add;int;8;64;value;aarch64;Fail -add;int;8;128;value;aarch64;Fail -add;int;16;1;value;aarch64;Success; -add;int;16;2;value;aarch64;Fail -add;int;16;4;value;aarch64;Success; -add;int;16;8;value;aarch64;Fail -add;int;16;16;value;aarch64;Fail -add;int;16;32;value;aarch64;Fail -add;int;16;64;value;aarch64;Fail -add;int;16;128;value;aarch64;Fail -add;int;32;1;value;aarch64;Success; -add;int;32;2;value;aarch64;Fail -add;int;32;4;value;aarch64;Success; -add;int;32;8;value;aarch64;Fail -add;int;32;16;value;aarch64;Fail -add;int;32;32;value;aarch64;Fail -add;int;32;64;value;aarch64;Fail -add;int;32;128;value;aarch64;Fail -add;int;64;1;value;aarch64;Success; -add;int;64;2;value;aarch64;Fail -add;int;64;4;value;aarch64;Fail -add;int;64;8;value;aarch64;Fail -add;int;64;16;value;aarch64;Fail -add;int;64;32;value;aarch64;Fail -add;int;64;64;value;aarch64;Fail -add;int;64;128;value;aarch64;Fail -mul;int;8;1;value;aarch64;Success; -mul;int;8;2;value;aarch64;Fail -mul;int;8;4;value;aarch64;Fail -mul;int;8;8;value;aarch64;Fail -mul;int;8;16;value;aarch64;Fail -mul;int;8;32;value;aarch64;Fail -mul;int;8;64;value;aarch64;Fail -mul;int;8;128;value;aarch64;Fail -mul;int;16;1;value;aarch64;Success; -mul;int;16;2;value;aarch64;Fail -mul;int;16;4;value;aarch64;Success; -mul;int;16;8;value;aarch64;Fail -mul;int;16;16;value;aarch64;Fail -mul;int;16;32;value;aarch64;Fail -mul;int;16;64;value;aarch64;Fail -mul;int;16;128;value;aarch64;Fail -mul;int;32;1;value;aarch64;Success; -mul;int;32;2;value;aarch64;Fail -mul;int;32;4;value;aarch64;Success; -mul;int;32;8;value;aarch64;Fail -mul;int;32;16;value;aarch64;Fail -mul;int;32;32;value;aarch64;Fail -mul;int;32;64;value;aarch64;Fail -mul;int;32;128;value;aarch64;Fail -mul;int;64;1;value;aarch64;Success; -mul;int;64;2;value;aarch64;Fail -mul;int;64;4;value;aarch64;Fail -mul;int;64;8;value;aarch64;Fail -mul;int;64;16;value;aarch64;Fail -mul;int;64;32;value;aarch64;Fail -mul;int;64;64;value;aarch64;Fail -mul;int;64;128;value;aarch64;Fail -sub;int;8;1;value;aarch64;Success; -sub;int;8;2;value;aarch64;Fail -sub;int;8;4;value;aarch64;Fail -sub;int;8;8;value;aarch64;Fail -sub;int;8;16;value;aarch64;Fail -sub;int;8;32;value;aarch64;Fail -sub;int;8;64;value;aarch64;Fail -sub;int;8;128;value;aarch64;Fail -sub;int;16;1;value;aarch64;Success; -sub;int;16;2;value;aarch64;Fail -sub;int;16;4;value;aarch64;Success; -sub;int;16;8;value;aarch64;Fail -sub;int;16;16;value;aarch64;Fail -sub;int;16;32;value;aarch64;Fail -sub;int;16;64;value;aarch64;Fail -sub;int;16;128;value;aarch64;Fail -sub;int;32;1;value;aarch64;Success; -sub;int;32;2;value;aarch64;Fail -sub;int;32;4;value;aarch64;Success; -sub;int;32;8;value;aarch64;Fail -sub;int;32;16;value;aarch64;Fail -sub;int;32;32;value;aarch64;Fail -sub;int;32;64;value;aarch64;Fail -sub;int;32;128;value;aarch64;Fail -sub;int;64;1;value;aarch64;Success; -sub;int;64;2;value;aarch64;Success; -sub;int;64;4;value;aarch64;Fail -sub;int;64;8;value;aarch64;Fail -sub;int;64;16;value;aarch64;Fail -sub;int;64;32;value;aarch64;Fail -sub;int;64;64;value;aarch64;Fail -sub;int;64;128;value;aarch64;Fail -div;int;8;1;value;aarch64;Success; -div;int;8;2;value;aarch64;Fail -div;int;8;4;value;aarch64;Fail -div;int;8;8;value;aarch64;Fail -div;int;8;16;value;aarch64;Fail -div;int;8;32;value;aarch64;Fail -div;int;8;64;value;aarch64;Fail -div;int;8;128;value;aarch64;Fail -div;int;16;1;value;aarch64;Success; -div;int;16;2;value;aarch64;Fail -div;int;16;4;value;aarch64;Fail -div;int;16;8;value;aarch64;Fail -div;int;16;16;value;aarch64;Fail -div;int;16;32;value;aarch64;Fail -div;int;16;64;value;aarch64;Fail -div;int;16;128;value;aarch64;Fail -div;int;32;1;value;aarch64;Success; -div;int;32;2;value;aarch64;Fail -div;int;32;4;value;aarch64;Fail -div;int;32;8;value;aarch64;Fail -div;int;32;16;value;aarch64;Fail -div;int;32;32;value;aarch64;Fail -div;int;32;64;value;aarch64;Fail -div;int;32;128;value;aarch64;Fail -div;int;64;1;value;aarch64;Success; -div;int;64;2;value;aarch64;Fail -div;int;64;4;value;aarch64;Fail -div;int;64;8;value;aarch64;Fail -div;int;64;16;value;aarch64;Fail -div;int;64;32;value;aarch64;Fail -div;int;64;64;value;aarch64;Fail -div;int;64;128;value;aarch64;Fail -add;flt;32;1;value;aarch64;Success; -add;flt;32;2;value;aarch64;Fail -add;flt;32;4;value;aarch64;Fail -add;flt;32;8;value;aarch64;Fail -add;flt;32;16;value;aarch64;Fail -add;flt;32;32;value;aarch64;Fail -add;flt;32;64;value;aarch64;Fail -add;flt;32;128;value;aarch64;Fail -add;flt;64;1;value;aarch64;Success; -add;flt;64;2;value;aarch64;Fail -add;flt;64;4;value;aarch64;Fail -add;flt;64;8;value;aarch64;Fail -add;flt;64;16;value;aarch64;Fail -add;flt;64;32;value;aarch64;Fail -add;flt;64;64;value;aarch64;Fail -add;flt;64;128;value;aarch64;Fail -mul;flt;32;1;value;aarch64;Success; -mul;flt;32;2;value;aarch64;Fail -mul;flt;32;4;value;aarch64;Fail -mul;flt;32;8;value;aarch64;Fail -mul;flt;32;16;value;aarch64;Fail -mul;flt;32;32;value;aarch64;Fail -mul;flt;32;64;value;aarch64;Fail -mul;flt;32;128;value;aarch64;Fail -mul;flt;64;1;value;aarch64;Success; -mul;flt;64;2;value;aarch64;Fail -mul;flt;64;4;value;aarch64;Fail -mul;flt;64;8;value;aarch64;Fail -mul;flt;64;16;value;aarch64;Fail -mul;flt;64;32;value;aarch64;Fail -mul;flt;64;64;value;aarch64;Fail -mul;flt;64;128;value;aarch64;Fail -sub;flt;32;1;value;aarch64;Success; -sub;flt;32;2;value;aarch64;Fail -sub;flt;32;4;value;aarch64;Fail -sub;flt;32;8;value;aarch64;Fail -sub;flt;32;16;value;aarch64;Fail -sub;flt;32;32;value;aarch64;Fail -sub;flt;32;64;value;aarch64;Fail -sub;flt;32;128;value;aarch64;Fail -sub;flt;64;1;value;aarch64;Success; -sub;flt;64;2;value;aarch64;Fail -sub;flt;64;4;value;aarch64;Fail -sub;flt;64;8;value;aarch64;Fail -sub;flt;64;16;value;aarch64;Fail -sub;flt;64;32;value;aarch64;Fail -sub;flt;64;64;value;aarch64;Fail -sub;flt;64;128;value;aarch64;Fail -div;flt;32;1;value;aarch64;Success; -div;flt;32;2;value;aarch64;Fail -div;flt;32;4;value;aarch64;Fail -div;flt;32;8;value;aarch64;Fail -div;flt;32;16;value;aarch64;Fail -div;flt;32;32;value;aarch64;Fail -div;flt;32;64;value;aarch64;Fail -div;flt;32;128;value;aarch64;Fail -div;flt;64;1;value;aarch64;Success; -div;flt;64;2;value;aarch64;Fail -div;flt;64;4;value;aarch64;Fail -div;flt;64;8;value;aarch64;Fail -div;flt;64;16;value;aarch64;Fail -div;flt;64;32;value;aarch64;Fail -div;flt;64;64;value;aarch64;Fail -div;flt;64;128;value;aarch64;Fail -mod;int;8;1;value;aarch64;Fail -mod;int;8;2;value;aarch64;Fail -mod;int;8;4;value;aarch64;Fail -mod;int;8;8;value;aarch64;Fail -mod;int;8;16;value;aarch64;Fail -mod;int;8;32;value;aarch64;Fail -mod;int;8;64;value;aarch64;Fail -mod;int;8;128;value;aarch64;Fail -mod;int;16;1;value;aarch64;Fail -mod;int;16;2;value;aarch64;Fail -mod;int;16;4;value;aarch64;Fail -mod;int;16;8;value;aarch64;Fail -mod;int;16;16;value;aarch64;Fail -mod;int;16;32;value;aarch64;Fail -mod;int;16;64;value;aarch64;Fail -mod;int;16;128;value;aarch64;Fail -mod;int;32;1;value;aarch64;Fail -mod;int;32;2;value;aarch64;Fail -mod;int;32;4;value;aarch64;Fail -mod;int;32;8;value;aarch64;Fail -mod;int;32;16;value;aarch64;Fail -mod;int;32;32;value;aarch64;Fail -mod;int;32;64;value;aarch64;Fail -mod;int;32;128;value;aarch64;Fail -mod;int;64;1;value;aarch64;Fail -mod;int;64;2;value;aarch64;Fail -mod;int;64;4;value;aarch64;Fail -mod;int;64;8;value;aarch64;Fail -mod;int;64;16;value;aarch64;Fail -mod;int;64;32;value;aarch64;Fail -mod;int;64;64;value;aarch64;Fail -mod;int;64;128;value;aarch64;Fail -or;int;8;1;value;aarch64;Success; -or;int;8;2;value;aarch64;Fail -or;int;8;4;value;aarch64;Fail -or;int;8;8;value;aarch64;Fail -or;int;8;16;value;aarch64;Fail -or;int;8;32;value;aarch64;Fail -or;int;8;64;value;aarch64;Fail -or;int;8;128;value;aarch64;Fail -or;int;16;1;value;aarch64;Success; -or;int;16;2;value;aarch64;Fail -or;int;16;4;value;aarch64;Success; -or;int;16;8;value;aarch64;Fail -or;int;16;16;value;aarch64;Fail -or;int;16;32;value;aarch64;Fail -or;int;16;64;value;aarch64;Fail -or;int;16;128;value;aarch64;Fail -or;int;32;1;value;aarch64;Success; -or;int;32;2;value;aarch64;Fail -or;int;32;4;value;aarch64;Success; -or;int;32;8;value;aarch64;Fail -or;int;32;16;value;aarch64;Fail -or;int;32;32;value;aarch64;Fail -or;int;32;64;value;aarch64;Fail -or;int;32;128;value;aarch64;Fail -or;int;64;1;value;aarch64;Success; -or;int;64;2;value;aarch64;Fail -or;int;64;4;value;aarch64;Fail -or;int;64;8;value;aarch64;Fail -or;int;64;16;value;aarch64;Fail -or;int;64;32;value;aarch64;Fail -or;int;64;64;value;aarch64;Fail -or;int;64;128;value;aarch64;Fail -and;int;8;1;value;aarch64;Success; -and;int;8;2;value;aarch64;Fail -and;int;8;4;value;aarch64;Fail -and;int;8;8;value;aarch64;Fail -and;int;8;16;value;aarch64;Fail -and;int;8;32;value;aarch64;Fail -and;int;8;64;value;aarch64;Fail -and;int;8;128;value;aarch64;Fail -and;int;16;1;value;aarch64;Success; -and;int;16;2;value;aarch64;Fail -and;int;16;4;value;aarch64;Success; -and;int;16;8;value;aarch64;Fail -and;int;16;16;value;aarch64;Fail -and;int;16;32;value;aarch64;Fail -and;int;16;64;value;aarch64;Fail -and;int;16;128;value;aarch64;Fail -and;int;32;1;value;aarch64;Success; -and;int;32;2;value;aarch64;Fail -and;int;32;4;value;aarch64;Success; -and;int;32;8;value;aarch64;Fail -and;int;32;16;value;aarch64;Fail -and;int;32;32;value;aarch64;Fail -and;int;32;64;value;aarch64;Fail -and;int;32;128;value;aarch64;Fail -and;int;64;1;value;aarch64;Success; -and;int;64;2;value;aarch64;Fail -and;int;64;4;value;aarch64;Fail -and;int;64;8;value;aarch64;Fail -and;int;64;16;value;aarch64;Fail -and;int;64;32;value;aarch64;Fail -and;int;64;64;value;aarch64;Fail -and;int;64;128;value;aarch64;Fail -xor;int;8;1;value;aarch64;Success; -xor;int;8;2;value;aarch64;Fail -xor;int;8;4;value;aarch64;Fail -xor;int;8;8;value;aarch64;Fail -xor;int;8;16;value;aarch64;Fail -xor;int;8;32;value;aarch64;Fail -xor;int;8;64;value;aarch64;Fail -xor;int;8;128;value;aarch64;Fail -xor;int;16;1;value;aarch64;Success; -xor;int;16;2;value;aarch64;Fail -xor;int;16;4;value;aarch64;Success; -xor;int;16;8;value;aarch64;Fail -xor;int;16;16;value;aarch64;Fail -xor;int;16;32;value;aarch64;Fail -xor;int;16;64;value;aarch64;Fail -xor;int;16;128;value;aarch64;Fail -xor;int;32;1;value;aarch64;Success; -xor;int;32;2;value;aarch64;Fail -xor;int;32;4;value;aarch64;Success; -xor;int;32;8;value;aarch64;Fail -xor;int;32;16;value;aarch64;Fail -xor;int;32;32;value;aarch64;Fail -xor;int;32;64;value;aarch64;Fail -xor;int;32;128;value;aarch64;Fail -xor;int;64;1;value;aarch64;Success; -xor;int;64;2;value;aarch64;Fail -xor;int;64;4;value;aarch64;Fail -xor;int;64;8;value;aarch64;Fail -xor;int;64;16;value;aarch64;Fail -xor;int;64;32;value;aarch64;Fail -xor;int;64;64;value;aarch64;Fail -xor;int;64;128;value;aarch64;Fail -sl;int;8;1;value;aarch64;Success; -sl;int;8;2;value;aarch64;Fail -sl;int;8;4;value;aarch64;Fail -sl;int;8;8;value;aarch64;Fail -sl;int;8;16;value;aarch64;Fail -sl;int;8;32;value;aarch64;Fail -sl;int;8;64;value;aarch64;Fail -sl;int;8;128;value;aarch64;Fail -sl;int;16;1;value;aarch64;Success; -sl;int;16;2;value;aarch64;Fail -sl;int;16;4;value;aarch64;Fail -sl;int;16;8;value;aarch64;Fail -sl;int;16;16;value;aarch64;Fail -sl;int;16;32;value;aarch64;Fail -sl;int;16;64;value;aarch64;Fail -sl;int;16;128;value;aarch64;Fail -sl;int;32;1;value;aarch64;Success; -sl;int;32;2;value;aarch64;Fail -sl;int;32;4;value;aarch64;Fail -sl;int;32;8;value;aarch64;Fail -sl;int;32;16;value;aarch64;Fail -sl;int;32;32;value;aarch64;Fail -sl;int;32;64;value;aarch64;Fail -sl;int;32;128;value;aarch64;Fail -sl;int;64;1;value;aarch64;Success; -sl;int;64;2;value;aarch64;Fail -sl;int;64;4;value;aarch64;Fail -sl;int;64;8;value;aarch64;Fail -sl;int;64;16;value;aarch64;Fail -sl;int;64;32;value;aarch64;Fail -sl;int;64;64;value;aarch64;Fail -sl;int;64;128;value;aarch64;Fail -sr;int;8;1;value;aarch64;Success; -sr;int;8;2;value;aarch64;Fail -sr;int;8;4;value;aarch64;Fail -sr;int;8;8;value;aarch64;Fail -sr;int;8;16;value;aarch64;Fail -sr;int;8;32;value;aarch64;Fail -sr;int;8;64;value;aarch64;Fail -sr;int;8;128;value;aarch64;Fail -sr;int;16;1;value;aarch64;Success; -sr;int;16;2;value;aarch64;Fail -sr;int;16;4;value;aarch64;Fail -sr;int;16;8;value;aarch64;Fail -sr;int;16;16;value;aarch64;Fail -sr;int;16;32;value;aarch64;Fail -sr;int;16;64;value;aarch64;Fail -sr;int;16;128;value;aarch64;Fail -sr;int;32;1;value;aarch64;Success; -sr;int;32;2;value;aarch64;Fail -sr;int;32;4;value;aarch64;Fail -sr;int;32;8;value;aarch64;Fail -sr;int;32;16;value;aarch64;Fail -sr;int;32;32;value;aarch64;Fail -sr;int;32;64;value;aarch64;Fail -sr;int;32;128;value;aarch64;Fail -sr;int;64;1;value;aarch64;Success; -sr;int;64;2;value;aarch64;Fail -sr;int;64;4;value;aarch64;Fail -sr;int;64;8;value;aarch64;Fail -sr;int;64;16;value;aarch64;Fail -sr;int;64;32;value;aarch64;Fail -sr;int;64;64;value;aarch64;Fail -sr;int;64;128;value;aarch64;Fail -add;int;8;1;value;riscv;Success; -add;int;8;2;value;riscv;Fail -add;int;8;4;value;riscv;Fail -add;int;8;8;value;riscv;Fail -add;int;8;16;value;riscv;Fail -add;int;8;32;value;riscv;Fail -add;int;8;64;value;riscv;Fail -add;int;8;128;value;riscv;Fail -add;int;16;1;value;riscv;Success; -add;int;16;2;value;riscv;Fail -add;int;16;4;value;riscv;Fail -add;int;16;8;value;riscv;Fail -add;int;16;16;value;riscv;Fail -add;int;16;32;value;riscv;Fail -add;int;16;64;value;riscv;Fail -add;int;16;128;value;riscv;Fail -add;int;32;1;value;riscv;Success; -add;int;32;2;value;riscv;Fail -add;int;32;4;value;riscv;Fail -add;int;32;8;value;riscv;Fail -add;int;32;16;value;riscv;Fail -add;int;32;32;value;riscv;Fail -add;int;32;64;value;riscv;Fail -add;int;32;128;value;riscv;Fail -add;int;64;1;value;riscv;Fail -add;int;64;2;value;riscv;Fail -add;int;64;4;value;riscv;Fail -add;int;64;8;value;riscv;Fail -add;int;64;16;value;riscv;Fail -add;int;64;32;value;riscv;Fail -add;int;64;64;value;riscv;Fail -add;int;64;128;value;riscv;Fail -mul;int;8;1;value;riscv;Success; -mul;int;8;2;value;riscv;Fail -mul;int;8;4;value;riscv;Fail -mul;int;8;8;value;riscv;Fail -mul;int;8;16;value;riscv;Fail -mul;int;8;32;value;riscv;Fail -mul;int;8;64;value;riscv;Fail -mul;int;8;128;value;riscv;Fail -mul;int;16;1;value;riscv;Success; -mul;int;16;2;value;riscv;Fail -mul;int;16;4;value;riscv;Fail -mul;int;16;8;value;riscv;Fail -mul;int;16;16;value;riscv;Fail -mul;int;16;32;value;riscv;Fail -mul;int;16;64;value;riscv;Fail -mul;int;16;128;value;riscv;Fail -mul;int;32;1;value;riscv;Success; -mul;int;32;2;value;riscv;Fail -mul;int;32;4;value;riscv;Fail -mul;int;32;8;value;riscv;Fail -mul;int;32;16;value;riscv;Fail -mul;int;32;32;value;riscv;Fail -mul;int;32;64;value;riscv;Fail -mul;int;32;128;value;riscv;Fail -mul;int;64;1;value;riscv;Fail -mul;int;64;2;value;riscv;Fail -mul;int;64;4;value;riscv;Fail -mul;int;64;8;value;riscv;Fail -mul;int;64;16;value;riscv;Fail -mul;int;64;32;value;riscv;Fail -mul;int;64;64;value;riscv;Fail -mul;int;64;128;value;riscv;Fail -sub;int;8;1;value;riscv;Success; -sub;int;8;2;value;riscv;Fail -sub;int;8;4;value;riscv;Fail -sub;int;8;8;value;riscv;Fail -sub;int;8;16;value;riscv;Fail -sub;int;8;32;value;riscv;Fail -sub;int;8;64;value;riscv;Fail -sub;int;8;128;value;riscv;Fail -sub;int;16;1;value;riscv;Success; -sub;int;16;2;value;riscv;Fail -sub;int;16;4;value;riscv;Fail -sub;int;16;8;value;riscv;Fail -sub;int;16;16;value;riscv;Fail -sub;int;16;32;value;riscv;Fail -sub;int;16;64;value;riscv;Fail -sub;int;16;128;value;riscv;Fail -sub;int;32;1;value;riscv;Success; -sub;int;32;2;value;riscv;Fail -sub;int;32;4;value;riscv;Fail -sub;int;32;8;value;riscv;Fail -sub;int;32;16;value;riscv;Fail -sub;int;32;32;value;riscv;Fail -sub;int;32;64;value;riscv;Fail -sub;int;32;128;value;riscv;Fail -sub;int;64;1;value;riscv;Fail -sub;int;64;2;value;riscv;Fail -sub;int;64;4;value;riscv;Fail -sub;int;64;8;value;riscv;Fail -sub;int;64;16;value;riscv;Fail -sub;int;64;32;value;riscv;Fail -sub;int;64;64;value;riscv;Fail -sub;int;64;128;value;riscv;Fail -div;int;8;1;value;riscv;Success; -div;int;8;2;value;riscv;Fail -div;int;8;4;value;riscv;Fail -div;int;8;8;value;riscv;Fail -div;int;8;16;value;riscv;Fail -div;int;8;32;value;riscv;Fail -div;int;8;64;value;riscv;Fail -div;int;8;128;value;riscv;Fail -div;int;16;1;value;riscv;Success; -div;int;16;2;value;riscv;Fail -div;int;16;4;value;riscv;Fail -div;int;16;8;value;riscv;Fail -div;int;16;16;value;riscv;Fail -div;int;16;32;value;riscv;Fail -div;int;16;64;value;riscv;Fail -div;int;16;128;value;riscv;Fail -div;int;32;1;value;riscv;Success; -div;int;32;2;value;riscv;Fail -div;int;32;4;value;riscv;Fail -div;int;32;8;value;riscv;Fail -div;int;32;16;value;riscv;Fail -div;int;32;32;value;riscv;Fail -div;int;32;64;value;riscv;Fail -div;int;32;128;value;riscv;Fail -div;int;64;1;value;riscv;Fail -div;int;64;2;value;riscv;Fail -div;int;64;4;value;riscv;Fail -div;int;64;8;value;riscv;Fail -div;int;64;16;value;riscv;Fail -div;int;64;32;value;riscv;Fail -div;int;64;64;value;riscv;Fail -div;int;64;128;value;riscv;Fail -add;flt;32;1;value;riscv;Success; -add;flt;32;2;value;riscv;Fail -add;flt;32;4;value;riscv;Fail -add;flt;32;8;value;riscv;Fail -add;flt;32;16;value;riscv;Fail -add;flt;32;32;value;riscv;Fail -add;flt;32;64;value;riscv;Fail -add;flt;32;128;value;riscv;Fail -add;flt;64;1;value;riscv;Success; -add;flt;64;2;value;riscv;Fail -add;flt;64;4;value;riscv;Fail -add;flt;64;8;value;riscv;Fail -add;flt;64;16;value;riscv;Fail -add;flt;64;32;value;riscv;Fail -add;flt;64;64;value;riscv;Fail -add;flt;64;128;value;riscv;Fail -mul;flt;32;1;value;riscv;Success; -mul;flt;32;2;value;riscv;Fail -mul;flt;32;4;value;riscv;Fail -mul;flt;32;8;value;riscv;Fail -mul;flt;32;16;value;riscv;Fail -mul;flt;32;32;value;riscv;Fail -mul;flt;32;64;value;riscv;Fail -mul;flt;32;128;value;riscv;Fail -mul;flt;64;1;value;riscv;Fail -mul;flt;64;2;value;riscv;Fail -mul;flt;64;4;value;riscv;Fail -mul;flt;64;8;value;riscv;Fail -mul;flt;64;16;value;riscv;Fail -mul;flt;64;32;value;riscv;Fail -mul;flt;64;64;value;riscv;Fail -mul;flt;64;128;value;riscv;Fail -sub;flt;32;1;value;riscv;Success; -sub;flt;32;2;value;riscv;Fail -sub;flt;32;4;value;riscv;Fail -sub;flt;32;8;value;riscv;Fail -sub;flt;32;16;value;riscv;Fail -sub;flt;32;32;value;riscv;Fail -sub;flt;32;64;value;riscv;Fail -sub;flt;32;128;value;riscv;Fail -sub;flt;64;1;value;riscv;Fail -sub;flt;64;2;value;riscv;Fail -sub;flt;64;4;value;riscv;Fail -sub;flt;64;8;value;riscv;Fail -sub;flt;64;16;value;riscv;Fail -sub;flt;64;32;value;riscv;Fail -sub;flt;64;64;value;riscv;Fail -sub;flt;64;128;value;riscv;Fail -div;flt;32;1;value;riscv;Success; -div;flt;32;2;value;riscv;Fail -div;flt;32;4;value;riscv;Fail -div;flt;32;8;value;riscv;Fail -div;flt;32;16;value;riscv;Fail -div;flt;32;32;value;riscv;Fail -div;flt;32;64;value;riscv;Fail -div;flt;32;128;value;riscv;Fail -div;flt;64;1;value;riscv;Success; -div;flt;64;2;value;riscv;Fail -div;flt;64;4;value;riscv;Fail -div;flt;64;8;value;riscv;Fail -div;flt;64;16;value;riscv;Fail -div;flt;64;32;value;riscv;Fail -div;flt;64;64;value;riscv;Fail -div;flt;64;128;value;riscv;Fail -mod;int;8;1;value;riscv;Fail -mod;int;8;2;value;riscv;Fail -mod;int;8;4;value;riscv;Fail -mod;int;8;8;value;riscv;Fail -mod;int;8;16;value;riscv;Fail -mod;int;8;32;value;riscv;Fail -mod;int;8;64;value;riscv;Fail -mod;int;8;128;value;riscv;Fail -mod;int;16;1;value;riscv;Fail -mod;int;16;2;value;riscv;Fail -mod;int;16;4;value;riscv;Fail -mod;int;16;8;value;riscv;Fail -mod;int;16;16;value;riscv;Fail -mod;int;16;32;value;riscv;Fail -mod;int;16;64;value;riscv;Fail -mod;int;16;128;value;riscv;Fail -mod;int;32;1;value;riscv;Fail -mod;int;32;2;value;riscv;Fail -mod;int;32;4;value;riscv;Fail -mod;int;32;8;value;riscv;Fail -mod;int;32;16;value;riscv;Fail -mod;int;32;32;value;riscv;Fail -mod;int;32;64;value;riscv;Fail -mod;int;32;128;value;riscv;Fail -mod;int;64;1;value;riscv;Fail -mod;int;64;2;value;riscv;Fail -mod;int;64;4;value;riscv;Fail -mod;int;64;8;value;riscv;Fail -mod;int;64;16;value;riscv;Fail -mod;int;64;32;value;riscv;Fail -mod;int;64;64;value;riscv;Fail -mod;int;64;128;value;riscv;Fail -or;int;8;1;value;riscv;Success; -or;int;8;2;value;riscv;Fail -or;int;8;4;value;riscv;Fail -or;int;8;8;value;riscv;Fail -or;int;8;16;value;riscv;Fail -or;int;8;32;value;riscv;Fail -or;int;8;64;value;riscv;Fail -or;int;8;128;value;riscv;Fail -or;int;16;1;value;riscv;Success; -or;int;16;2;value;riscv;Fail -or;int;16;4;value;riscv;Fail -or;int;16;8;value;riscv;Fail -or;int;16;16;value;riscv;Fail -or;int;16;32;value;riscv;Fail -or;int;16;64;value;riscv;Fail -or;int;16;128;value;riscv;Fail -or;int;32;1;value;riscv;Success; -or;int;32;2;value;riscv;Fail -or;int;32;4;value;riscv;Fail -or;int;32;8;value;riscv;Fail -or;int;32;16;value;riscv;Fail -or;int;32;32;value;riscv;Fail -or;int;32;64;value;riscv;Fail -or;int;32;128;value;riscv;Fail -or;int;64;1;value;riscv;Fail -or;int;64;2;value;riscv;Fail -or;int;64;4;value;riscv;Fail -or;int;64;8;value;riscv;Fail -or;int;64;16;value;riscv;Fail -or;int;64;32;value;riscv;Fail -or;int;64;64;value;riscv;Fail -or;int;64;128;value;riscv;Fail -and;int;8;1;value;riscv;Success; -and;int;8;2;value;riscv;Fail -and;int;8;4;value;riscv;Fail -and;int;8;8;value;riscv;Fail -and;int;8;16;value;riscv;Fail -and;int;8;32;value;riscv;Fail -and;int;8;64;value;riscv;Fail -and;int;8;128;value;riscv;Fail -and;int;16;1;value;riscv;Success; -and;int;16;2;value;riscv;Fail -and;int;16;4;value;riscv;Fail -and;int;16;8;value;riscv;Fail -and;int;16;16;value;riscv;Fail -and;int;16;32;value;riscv;Fail -and;int;16;64;value;riscv;Fail -and;int;16;128;value;riscv;Fail -and;int;32;1;value;riscv;Success; -and;int;32;2;value;riscv;Fail -and;int;32;4;value;riscv;Fail -and;int;32;8;value;riscv;Fail -and;int;32;16;value;riscv;Fail -and;int;32;32;value;riscv;Fail -and;int;32;64;value;riscv;Fail -and;int;32;128;value;riscv;Fail -and;int;64;1;value;riscv;Fail -and;int;64;2;value;riscv;Fail -and;int;64;4;value;riscv;Fail -and;int;64;8;value;riscv;Fail -and;int;64;16;value;riscv;Fail -and;int;64;32;value;riscv;Fail -and;int;64;64;value;riscv;Fail -and;int;64;128;value;riscv;Fail -xor;int;8;1;value;riscv;Success; -xor;int;8;2;value;riscv;Fail -xor;int;8;4;value;riscv;Fail -xor;int;8;8;value;riscv;Fail -xor;int;8;16;value;riscv;Fail -xor;int;8;32;value;riscv;Fail -xor;int;8;64;value;riscv;Fail -xor;int;8;128;value;riscv;Fail -xor;int;16;1;value;riscv;Success; -xor;int;16;2;value;riscv;Fail -xor;int;16;4;value;riscv;Fail -xor;int;16;8;value;riscv;Fail -xor;int;16;16;value;riscv;Fail -xor;int;16;32;value;riscv;Fail -xor;int;16;64;value;riscv;Fail -xor;int;16;128;value;riscv;Fail -xor;int;32;1;value;riscv;Success; -xor;int;32;2;value;riscv;Fail -xor;int;32;4;value;riscv;Fail -xor;int;32;8;value;riscv;Fail -xor;int;32;16;value;riscv;Fail -xor;int;32;32;value;riscv;Fail -xor;int;32;64;value;riscv;Fail -xor;int;32;128;value;riscv;Fail -xor;int;64;1;value;riscv;Fail -xor;int;64;2;value;riscv;Fail -xor;int;64;4;value;riscv;Fail -xor;int;64;8;value;riscv;Fail -xor;int;64;16;value;riscv;Fail -xor;int;64;32;value;riscv;Fail -xor;int;64;64;value;riscv;Fail -xor;int;64;128;value;riscv;Fail -sl;int;8;1;value;riscv;Success; -sl;int;8;2;value;riscv;Fail -sl;int;8;4;value;riscv;Fail -sl;int;8;8;value;riscv;Fail -sl;int;8;16;value;riscv;Fail -sl;int;8;32;value;riscv;Fail -sl;int;8;64;value;riscv;Fail -sl;int;8;128;value;riscv;Fail -sl;int;16;1;value;riscv;Success; -sl;int;16;2;value;riscv;Fail -sl;int;16;4;value;riscv;Fail -sl;int;16;8;value;riscv;Fail -sl;int;16;16;value;riscv;Fail -sl;int;16;32;value;riscv;Fail -sl;int;16;64;value;riscv;Fail -sl;int;16;128;value;riscv;Fail -sl;int;32;1;value;riscv;Success; -sl;int;32;2;value;riscv;Fail -sl;int;32;4;value;riscv;Fail -sl;int;32;8;value;riscv;Fail -sl;int;32;16;value;riscv;Fail -sl;int;32;32;value;riscv;Fail -sl;int;32;64;value;riscv;Fail -sl;int;32;128;value;riscv;Fail -sl;int;64;1;value;riscv;Fail -sl;int;64;2;value;riscv;Fail -sl;int;64;4;value;riscv;Fail -sl;int;64;8;value;riscv;Fail -sl;int;64;16;value;riscv;Fail -sl;int;64;32;value;riscv;Fail -sl;int;64;64;value;riscv;Fail -sl;int;64;128;value;riscv;Fail -sr;int;8;1;value;riscv;Success; -sr;int;8;2;value;riscv;Fail -sr;int;8;4;value;riscv;Fail -sr;int;8;8;value;riscv;Fail -sr;int;8;16;value;riscv;Fail -sr;int;8;32;value;riscv;Fail -sr;int;8;64;value;riscv;Fail -sr;int;8;128;value;riscv;Fail -sr;int;16;1;value;riscv;Success; -sr;int;16;2;value;riscv;Fail -sr;int;16;4;value;riscv;Fail -sr;int;16;8;value;riscv;Fail -sr;int;16;16;value;riscv;Fail -sr;int;16;32;value;riscv;Fail -sr;int;16;64;value;riscv;Fail -sr;int;16;128;value;riscv;Fail -sr;int;32;1;value;riscv;Success; -sr;int;32;2;value;riscv;Fail -sr;int;32;4;value;riscv;Fail -sr;int;32;8;value;riscv;Fail -sr;int;32;16;value;riscv;Fail -sr;int;32;32;value;riscv;Fail -sr;int;32;64;value;riscv;Fail -sr;int;32;128;value;riscv;Fail -sr;int;64;1;value;riscv;Fail -sr;int;64;2;value;riscv;Fail -sr;int;64;4;value;riscv;Fail -sr;int;64;8;value;riscv;Fail -sr;int;64;16;value;riscv;Fail -sr;int;64;32;value;riscv;Fail -sr;int;64;64;value;riscv;Fail -sr;int;64;128;value;riscv;Fail -add;int;8;1;value;power;Success; -add;int;8;2;value;power;Fail -add;int;8;4;value;power;Fail -add;int;8;8;value;power;Fail -add;int;8;16;value;power;Fail -add;int;8;32;value;power;Fail -add;int;8;64;value;power;Fail -add;int;8;128;value;power;Fail -add;int;16;1;value;power;Success; -add;int;16;2;value;power;Fail -add;int;16;4;value;power;Fail -add;int;16;8;value;power;Fail -add;int;16;16;value;power;Fail -add;int;16;32;value;power;Fail -add;int;16;64;value;power;Fail -add;int;16;128;value;power;Fail -add;int;32;1;value;power;Success; -add;int;32;2;value;power;Fail -add;int;32;4;value;power;Fail -add;int;32;8;value;power;Fail -add;int;32;16;value;power;Fail -add;int;32;32;value;power;Fail -add;int;32;64;value;power;Fail -add;int;32;128;value;power;Fail -add;int;64;1;value;power;Fail -add;int;64;2;value;power;Fail -add;int;64;4;value;power;Fail -add;int;64;8;value;power;Fail -add;int;64;16;value;power;Fail -add;int;64;32;value;power;Fail -add;int;64;64;value;power;Fail -add;int;64;128;value;power;Fail -mul;int;8;1;value;power;Success; -mul;int;8;2;value;power;Fail -mul;int;8;4;value;power;Fail -mul;int;8;8;value;power;Fail -mul;int;8;16;value;power;Fail -mul;int;8;32;value;power;Fail -mul;int;8;64;value;power;Fail -mul;int;8;128;value;power;Fail -mul;int;16;1;value;power;Success; -mul;int;16;2;value;power;Fail -mul;int;16;4;value;power;Fail -mul;int;16;8;value;power;Fail -mul;int;16;16;value;power;Fail -mul;int;16;32;value;power;Fail -mul;int;16;64;value;power;Fail -mul;int;16;128;value;power;Fail -mul;int;32;1;value;power;Success; -mul;int;32;2;value;power;Fail -mul;int;32;4;value;power;Fail -mul;int;32;8;value;power;Fail -mul;int;32;16;value;power;Fail -mul;int;32;32;value;power;Fail -mul;int;32;64;value;power;Fail -mul;int;32;128;value;power;Fail -mul;int;64;1;value;power;Fail -mul;int;64;2;value;power;Fail -mul;int;64;4;value;power;Fail -mul;int;64;8;value;power;Fail -mul;int;64;16;value;power;Fail -mul;int;64;32;value;power;Fail -mul;int;64;64;value;power;Fail -mul;int;64;128;value;power;Fail -sub;int;8;1;value;power;Success; -sub;int;8;2;value;power;Fail -sub;int;8;4;value;power;Fail -sub;int;8;8;value;power;Fail -sub;int;8;16;value;power;Fail -sub;int;8;32;value;power;Fail -sub;int;8;64;value;power;Fail -sub;int;8;128;value;power;Fail -sub;int;16;1;value;power;Success; -sub;int;16;2;value;power;Fail -sub;int;16;4;value;power;Fail -sub;int;16;8;value;power;Fail -sub;int;16;16;value;power;Fail -sub;int;16;32;value;power;Fail -sub;int;16;64;value;power;Fail -sub;int;16;128;value;power;Fail -sub;int;32;1;value;power;Success; -sub;int;32;2;value;power;Fail -sub;int;32;4;value;power;Fail -sub;int;32;8;value;power;Fail -sub;int;32;16;value;power;Fail -sub;int;32;32;value;power;Fail -sub;int;32;64;value;power;Fail -sub;int;32;128;value;power;Fail -sub;int;64;1;value;power;Fail -sub;int;64;2;value;power;Fail -sub;int;64;4;value;power;Fail -sub;int;64;8;value;power;Fail -sub;int;64;16;value;power;Fail -sub;int;64;32;value;power;Fail -sub;int;64;64;value;power;Fail -sub;int;64;128;value;power;Fail -div;int;8;1;value;power;Success; -div;int;8;2;value;power;Fail -div;int;8;4;value;power;Fail -div;int;8;8;value;power;Fail -div;int;8;16;value;power;Fail -div;int;8;32;value;power;Fail -div;int;8;64;value;power;Fail -div;int;8;128;value;power;Fail -div;int;16;1;value;power;Success; -div;int;16;2;value;power;Fail -div;int;16;4;value;power;Fail -div;int;16;8;value;power;Fail -div;int;16;16;value;power;Fail -div;int;16;32;value;power;Fail -div;int;16;64;value;power;Fail -div;int;16;128;value;power;Fail -div;int;32;1;value;power;Success; -div;int;32;2;value;power;Fail -div;int;32;4;value;power;Fail -div;int;32;8;value;power;Fail -div;int;32;16;value;power;Fail -div;int;32;32;value;power;Fail -div;int;32;64;value;power;Fail -div;int;32;128;value;power;Fail -div;int;64;1;value;power;Fail -div;int;64;2;value;power;Fail -div;int;64;4;value;power;Fail -div;int;64;8;value;power;Fail -div;int;64;16;value;power;Fail -div;int;64;32;value;power;Fail -div;int;64;64;value;power;Fail -div;int;64;128;value;power;Fail -add;flt;32;1;value;power;Success; -add;flt;32;2;value;power;Fail -add;flt;32;4;value;power;Fail -add;flt;32;8;value;power;Fail -add;flt;32;16;value;power;Fail -add;flt;32;32;value;power;Fail -add;flt;32;64;value;power;Fail -add;flt;32;128;value;power;Fail -add;flt;64;1;value;power;Success; -add;flt;64;2;value;power;Fail -add;flt;64;4;value;power;Fail -add;flt;64;8;value;power;Fail -add;flt;64;16;value;power;Fail -add;flt;64;32;value;power;Fail -add;flt;64;64;value;power;Fail -add;flt;64;128;value;power;Fail -mul;flt;32;1;value;power;Success; -mul;flt;32;2;value;power;Fail -mul;flt;32;4;value;power;Fail -mul;flt;32;8;value;power;Fail -mul;flt;32;16;value;power;Fail -mul;flt;32;32;value;power;Fail -mul;flt;32;64;value;power;Fail -mul;flt;32;128;value;power;Fail -mul;flt;64;1;value;power;Success; -mul;flt;64;2;value;power;Fail -mul;flt;64;4;value;power;Fail -mul;flt;64;8;value;power;Fail -mul;flt;64;16;value;power;Fail -mul;flt;64;32;value;power;Fail -mul;flt;64;64;value;power;Fail -mul;flt;64;128;value;power;Fail -sub;flt;32;1;value;power;Success; -sub;flt;32;2;value;power;Fail -sub;flt;32;4;value;power;Fail -sub;flt;32;8;value;power;Fail -sub;flt;32;16;value;power;Fail -sub;flt;32;32;value;power;Fail -sub;flt;32;64;value;power;Fail -sub;flt;32;128;value;power;Fail -sub;flt;64;1;value;power;Success; -sub;flt;64;2;value;power;Fail -sub;flt;64;4;value;power;Fail -sub;flt;64;8;value;power;Fail -sub;flt;64;16;value;power;Fail -sub;flt;64;32;value;power;Fail -sub;flt;64;64;value;power;Fail -sub;flt;64;128;value;power;Fail -div;flt;32;1;value;power;Success; -div;flt;32;2;value;power;Fail -div;flt;32;4;value;power;Fail -div;flt;32;8;value;power;Fail -div;flt;32;16;value;power;Fail -div;flt;32;32;value;power;Fail -div;flt;32;64;value;power;Fail -div;flt;32;128;value;power;Fail -div;flt;64;1;value;power;Success; -div;flt;64;2;value;power;Fail -div;flt;64;4;value;power;Fail -div;flt;64;8;value;power;Fail -div;flt;64;16;value;power;Fail -div;flt;64;32;value;power;Fail -div;flt;64;64;value;power;Fail -div;flt;64;128;value;power;Fail -mod;int;8;1;value;power;Fail -mod;int;8;2;value;power;Fail -mod;int;8;4;value;power;Fail -mod;int;8;8;value;power;Fail -mod;int;8;16;value;power;Fail -mod;int;8;32;value;power;Fail -mod;int;8;64;value;power;Fail -mod;int;8;128;value;power;Fail -mod;int;16;1;value;power;Fail -mod;int;16;2;value;power;Fail -mod;int;16;4;value;power;Fail -mod;int;16;8;value;power;Fail -mod;int;16;16;value;power;Fail -mod;int;16;32;value;power;Fail -mod;int;16;64;value;power;Fail -mod;int;16;128;value;power;Fail -mod;int;32;1;value;power;Fail -mod;int;32;2;value;power;Fail -mod;int;32;4;value;power;Fail -mod;int;32;8;value;power;Fail -mod;int;32;16;value;power;Fail -mod;int;32;32;value;power;Fail -mod;int;32;64;value;power;Fail -mod;int;32;128;value;power;Fail -mod;int;64;1;value;power;Fail -mod;int;64;2;value;power;Fail -mod;int;64;4;value;power;Fail -mod;int;64;8;value;power;Fail -mod;int;64;16;value;power;Fail -mod;int;64;32;value;power;Fail -mod;int;64;64;value;power;Fail -mod;int;64;128;value;power;Fail -or;int;8;1;value;power;Success; -or;int;8;2;value;power;Fail -or;int;8;4;value;power;Fail -or;int;8;8;value;power;Fail -or;int;8;16;value;power;Fail -or;int;8;32;value;power;Fail -or;int;8;64;value;power;Fail -or;int;8;128;value;power;Fail -or;int;16;1;value;power;Success; -or;int;16;2;value;power;Fail -or;int;16;4;value;power;Fail -or;int;16;8;value;power;Fail -or;int;16;16;value;power;Fail -or;int;16;32;value;power;Fail -or;int;16;64;value;power;Fail -or;int;16;128;value;power;Fail -or;int;32;1;value;power;Success; -or;int;32;2;value;power;Fail -or;int;32;4;value;power;Fail -or;int;32;8;value;power;Fail -or;int;32;16;value;power;Fail -or;int;32;32;value;power;Fail -or;int;32;64;value;power;Fail -or;int;32;128;value;power;Fail -or;int;64;1;value;power;Fail -or;int;64;2;value;power;Fail -or;int;64;4;value;power;Fail -or;int;64;8;value;power;Fail -or;int;64;16;value;power;Fail -or;int;64;32;value;power;Fail -or;int;64;64;value;power;Fail -or;int;64;128;value;power;Fail -and;int;8;1;value;power;Success; -and;int;8;2;value;power;Fail -and;int;8;4;value;power;Fail -and;int;8;8;value;power;Fail -and;int;8;16;value;power;Fail -and;int;8;32;value;power;Fail -and;int;8;64;value;power;Fail -and;int;8;128;value;power;Fail -and;int;16;1;value;power;Success; -and;int;16;2;value;power;Fail -and;int;16;4;value;power;Fail -and;int;16;8;value;power;Fail -and;int;16;16;value;power;Fail -and;int;16;32;value;power;Fail -and;int;16;64;value;power;Fail -and;int;16;128;value;power;Fail -and;int;32;1;value;power;Success; -and;int;32;2;value;power;Fail -and;int;32;4;value;power;Fail -and;int;32;8;value;power;Fail -and;int;32;16;value;power;Fail -and;int;32;32;value;power;Fail -and;int;32;64;value;power;Fail -and;int;32;128;value;power;Fail -and;int;64;1;value;power;Fail -and;int;64;2;value;power;Fail -and;int;64;4;value;power;Fail -and;int;64;8;value;power;Fail -and;int;64;16;value;power;Fail -and;int;64;32;value;power;Fail -and;int;64;64;value;power;Fail -and;int;64;128;value;power;Fail -xor;int;8;1;value;power;Success; -xor;int;8;2;value;power;Fail -xor;int;8;4;value;power;Fail -xor;int;8;8;value;power;Fail -xor;int;8;16;value;power;Fail -xor;int;8;32;value;power;Fail -xor;int;8;64;value;power;Fail -xor;int;8;128;value;power;Fail -xor;int;16;1;value;power;Success; -xor;int;16;2;value;power;Fail -xor;int;16;4;value;power;Fail -xor;int;16;8;value;power;Fail -xor;int;16;16;value;power;Fail -xor;int;16;32;value;power;Fail -xor;int;16;64;value;power;Fail -xor;int;16;128;value;power;Fail -xor;int;32;1;value;power;Success; -xor;int;32;2;value;power;Fail -xor;int;32;4;value;power;Fail -xor;int;32;8;value;power;Fail -xor;int;32;16;value;power;Fail -xor;int;32;32;value;power;Fail -xor;int;32;64;value;power;Fail -xor;int;32;128;value;power;Fail -xor;int;64;1;value;power;Fail -xor;int;64;2;value;power;Fail -xor;int;64;4;value;power;Fail -xor;int;64;8;value;power;Fail -xor;int;64;16;value;power;Fail -xor;int;64;32;value;power;Fail -xor;int;64;64;value;power;Fail -xor;int;64;128;value;power;Fail -sl;int;8;1;value;power;Success; -sl;int;8;2;value;power;Fail -sl;int;8;4;value;power;Fail -sl;int;8;8;value;power;Fail -sl;int;8;16;value;power;Fail -sl;int;8;32;value;power;Fail -sl;int;8;64;value;power;Fail -sl;int;8;128;value;power;Fail -sl;int;16;1;value;power;Success; -sl;int;16;2;value;power;Fail -sl;int;16;4;value;power;Fail -sl;int;16;8;value;power;Fail -sl;int;16;16;value;power;Fail -sl;int;16;32;value;power;Fail -sl;int;16;64;value;power;Fail -sl;int;16;128;value;power;Fail -sl;int;32;1;value;power;Success; -sl;int;32;2;value;power;Fail -sl;int;32;4;value;power;Fail -sl;int;32;8;value;power;Fail -sl;int;32;16;value;power;Fail -sl;int;32;32;value;power;Fail -sl;int;32;64;value;power;Fail -sl;int;32;128;value;power;Fail -sl;int;64;1;value;power;Fail -sl;int;64;2;value;power;Fail -sl;int;64;4;value;power;Fail -sl;int;64;8;value;power;Fail -sl;int;64;16;value;power;Fail -sl;int;64;32;value;power;Fail -sl;int;64;64;value;power;Fail -sl;int;64;128;value;power;Fail -sr;int;8;1;value;power;Fail -sr;int;8;2;value;power;Fail -sr;int;8;4;value;power;Fail -sr;int;8;8;value;power;Fail -sr;int;8;16;value;power;Fail -sr;int;8;32;value;power;Fail -sr;int;8;64;value;power;Fail -sr;int;8;128;value;power;Fail -sr;int;16;1;value;power;Fail -sr;int;16;2;value;power;Fail -sr;int;16;4;value;power;Fail -sr;int;16;8;value;power;Fail -sr;int;16;16;value;power;Fail -sr;int;16;32;value;power;Fail -sr;int;16;64;value;power;Fail -sr;int;16;128;value;power;Fail -sr;int;32;1;value;power;Fail -sr;int;32;2;value;power;Fail -sr;int;32;4;value;power;Fail -sr;int;32;8;value;power;Fail -sr;int;32;16;value;power;Fail -sr;int;32;32;value;power;Fail -sr;int;32;64;value;power;Fail -sr;int;32;128;value;power;Fail -sr;int;64;1;value;power;Fail -sr;int;64;2;value;power;Fail -sr;int;64;4;value;power;Fail -sr;int;64;8;value;power;Fail -sr;int;64;16;value;power;Fail -sr;int;64;32;value;power;Fail -sr;int;64;64;value;power;Fail -sr;int;64;128;value;power;Fail -add;int;8;1;address;aarch64;Fail -add;int;8;2;address;aarch64;Fail -add;int;8;4;address;aarch64;Fail -add;int;8;8;address;aarch64;Success; -add;int;8;16;address;aarch64;Success; -add;int;8;32;address;aarch64;Fail -add;int;8;64;address;aarch64;Fail -add;int;8;128;address;aarch64;Fail -add;int;16;1;address;aarch64;Fail -add;int;16;2;address;aarch64;Fail -add;int;16;4;address;aarch64;Success; -add;int;16;8;address;aarch64;Success; -add;int;16;16;address;aarch64;Fail -add;int;16;32;address;aarch64;Fail -add;int;16;64;address;aarch64;Fail -add;int;16;128;address;aarch64;Fail -add;int;32;1;address;aarch64;Fail -add;int;32;2;address;aarch64;Success; -add;int;32;4;address;aarch64;Success; -add;int;32;8;address;aarch64;Fail -add;int;32;16;address;aarch64;Fail -add;int;32;32;address;aarch64;Fail -add;int;32;64;address;aarch64;Fail -add;int;32;128;address;aarch64;Fail -add;int;64;1;address;aarch64;Fail -add;int;64;2;address;aarch64;Fail -add;int;64;4;address;aarch64;Fail -add;int;64;8;address;aarch64;Fail -add;int;64;16;address;aarch64;Fail -add;int;64;32;address;aarch64;Fail -add;int;64;64;address;aarch64;Fail -add;int;64;128;address;aarch64;Fail -mul;int;8;1;address;aarch64;Fail -mul;int;8;2;address;aarch64;Fail -mul;int;8;4;address;aarch64;Fail -mul;int;8;8;address;aarch64;Fail -mul;int;8;16;address;aarch64;Fail -mul;int;8;32;address;aarch64;Fail -mul;int;8;64;address;aarch64;Fail -mul;int;8;128;address;aarch64;Fail -mul;int;16;1;address;aarch64;Fail -mul;int;16;2;address;aarch64;Fail -mul;int;16;4;address;aarch64;Success; -mul;int;16;8;address;aarch64;Success; -mul;int;16;16;address;aarch64;Fail -mul;int;16;32;address;aarch64;Fail -mul;int;16;64;address;aarch64;Fail -mul;int;16;128;address;aarch64;Fail -mul;int;32;1;address;aarch64;Fail -mul;int;32;2;address;aarch64;Success; -mul;int;32;4;address;aarch64;Success; -mul;int;32;8;address;aarch64;Fail -mul;int;32;16;address;aarch64;Fail -mul;int;32;32;address;aarch64;Fail -mul;int;32;64;address;aarch64;Fail -mul;int;32;128;address;aarch64;Fail -mul;int;64;1;address;aarch64;Fail -mul;int;64;2;address;aarch64;Fail -mul;int;64;4;address;aarch64;Fail -mul;int;64;8;address;aarch64;Fail -mul;int;64;16;address;aarch64;Fail -mul;int;64;32;address;aarch64;Fail -mul;int;64;64;address;aarch64;Fail -mul;int;64;128;address;aarch64;Fail -sub;int;8;1;address;aarch64;Fail -sub;int;8;2;address;aarch64;Fail -sub;int;8;4;address;aarch64;Fail -sub;int;8;8;address;aarch64;Success; -sub;int;8;16;address;aarch64;Success; -sub;int;8;32;address;aarch64;Fail -sub;int;8;64;address;aarch64;Fail -sub;int;8;128;address;aarch64;Fail -sub;int;16;1;address;aarch64;Fail -sub;int;16;2;address;aarch64;Fail -sub;int;16;4;address;aarch64;Success; -sub;int;16;8;address;aarch64;Success; -sub;int;16;16;address;aarch64;Fail -sub;int;16;32;address;aarch64;Fail -sub;int;16;64;address;aarch64;Fail -sub;int;16;128;address;aarch64;Fail -sub;int;32;1;address;aarch64;Fail -sub;int;32;2;address;aarch64;Success; -sub;int;32;4;address;aarch64;Success; -sub;int;32;8;address;aarch64;Fail -sub;int;32;16;address;aarch64;Fail -sub;int;32;32;address;aarch64;Fail -sub;int;32;64;address;aarch64;Fail -sub;int;32;128;address;aarch64;Fail -sub;int;64;1;address;aarch64;Fail -sub;int;64;2;address;aarch64;Fail -sub;int;64;4;address;aarch64;Fail -sub;int;64;8;address;aarch64;Fail -sub;int;64;16;address;aarch64;Fail -sub;int;64;32;address;aarch64;Fail -sub;int;64;64;address;aarch64;Fail -sub;int;64;128;address;aarch64;Fail -div;int;8;1;address;aarch64;Fail -div;int;8;2;address;aarch64;Fail -div;int;8;4;address;aarch64;Fail -div;int;8;8;address;aarch64;Fail -div;int;8;16;address;aarch64;Fail -div;int;8;32;address;aarch64;Fail -div;int;8;64;address;aarch64;Fail -div;int;8;128;address;aarch64;Fail -div;int;16;1;address;aarch64;Fail -div;int;16;2;address;aarch64;Fail -div;int;16;4;address;aarch64;Fail -div;int;16;8;address;aarch64;Fail -div;int;16;16;address;aarch64;Fail -div;int;16;32;address;aarch64;Fail -div;int;16;64;address;aarch64;Fail -div;int;16;128;address;aarch64;Fail -div;int;32;1;address;aarch64;Fail -div;int;32;2;address;aarch64;Fail -div;int;32;4;address;aarch64;Fail -div;int;32;8;address;aarch64;Fail -div;int;32;16;address;aarch64;Fail -div;int;32;32;address;aarch64;Fail -div;int;32;64;address;aarch64;Fail -div;int;32;128;address;aarch64;Fail -div;int;64;1;address;aarch64;Fail -div;int;64;2;address;aarch64;Fail -div;int;64;4;address;aarch64;Fail -div;int;64;8;address;aarch64;Fail -div;int;64;16;address;aarch64;Fail -div;int;64;32;address;aarch64;Fail -div;int;64;64;address;aarch64;Fail -div;int;64;128;address;aarch64;Fail -add;flt;32;1;address;aarch64;Fail -add;flt;32;2;address;aarch64;Fail -add;flt;32;4;address;aarch64;Fail -add;flt;32;8;address;aarch64;Fail -add;flt;32;16;address;aarch64;Fail -add;flt;32;32;address;aarch64;Fail -add;flt;32;64;address;aarch64;Fail -add;flt;32;128;address;aarch64;Fail -add;flt;64;1;address;aarch64;Fail -add;flt;64;2;address;aarch64;Fail -add;flt;64;4;address;aarch64;Fail -add;flt;64;8;address;aarch64;Fail -add;flt;64;16;address;aarch64;Fail -add;flt;64;32;address;aarch64;Fail -add;flt;64;64;address;aarch64;Fail -add;flt;64;128;address;aarch64;Fail -mul;flt;32;1;address;aarch64;Fail -mul;flt;32;2;address;aarch64;Fail -mul;flt;32;4;address;aarch64;Fail -mul;flt;32;8;address;aarch64;Fail -mul;flt;32;16;address;aarch64;Fail -mul;flt;32;32;address;aarch64;Fail -mul;flt;32;64;address;aarch64;Fail -mul;flt;32;128;address;aarch64;Fail -mul;flt;64;1;address;aarch64;Fail -mul;flt;64;2;address;aarch64;Fail -mul;flt;64;4;address;aarch64;Fail -mul;flt;64;8;address;aarch64;Fail -mul;flt;64;16;address;aarch64;Fail -mul;flt;64;32;address;aarch64;Fail -mul;flt;64;64;address;aarch64;Fail -mul;flt;64;128;address;aarch64;Fail -sub;flt;32;1;address;aarch64;Fail -sub;flt;32;2;address;aarch64;Fail -sub;flt;32;4;address;aarch64;Fail -sub;flt;32;8;address;aarch64;Fail -sub;flt;32;16;address;aarch64;Fail -sub;flt;32;32;address;aarch64;Fail -sub;flt;32;64;address;aarch64;Fail -sub;flt;32;128;address;aarch64;Fail -sub;flt;64;1;address;aarch64;Fail -sub;flt;64;2;address;aarch64;Fail -sub;flt;64;4;address;aarch64;Fail -sub;flt;64;8;address;aarch64;Fail -sub;flt;64;16;address;aarch64;Fail -sub;flt;64;32;address;aarch64;Fail -sub;flt;64;64;address;aarch64;Fail -sub;flt;64;128;address;aarch64;Fail -div;flt;32;1;address;aarch64;Fail -div;flt;32;2;address;aarch64;Fail -div;flt;32;4;address;aarch64;Fail -div;flt;32;8;address;aarch64;Fail -div;flt;32;16;address;aarch64;Fail -div;flt;32;32;address;aarch64;Fail -div;flt;32;64;address;aarch64;Fail -div;flt;32;128;address;aarch64;Fail -div;flt;64;1;address;aarch64;Fail -div;flt;64;2;address;aarch64;Fail -div;flt;64;4;address;aarch64;Fail -div;flt;64;8;address;aarch64;Fail -div;flt;64;16;address;aarch64;Fail -div;flt;64;32;address;aarch64;Fail -div;flt;64;64;address;aarch64;Fail -div;flt;64;128;address;aarch64;Fail -mod;int;8;1;address;aarch64;Fail -mod;int;8;2;address;aarch64;Fail -mod;int;8;4;address;aarch64;Fail -mod;int;8;8;address;aarch64;Fail -mod;int;8;16;address;aarch64;Fail -mod;int;8;32;address;aarch64;Fail -mod;int;8;64;address;aarch64;Fail -mod;int;8;128;address;aarch64;Fail -mod;int;16;1;address;aarch64;Fail -mod;int;16;2;address;aarch64;Fail -mod;int;16;4;address;aarch64;Fail -mod;int;16;8;address;aarch64;Fail -mod;int;16;16;address;aarch64;Fail -mod;int;16;32;address;aarch64;Fail -mod;int;16;64;address;aarch64;Fail -mod;int;16;128;address;aarch64;Fail -mod;int;32;1;address;aarch64;Fail -mod;int;32;2;address;aarch64;Fail -mod;int;32;4;address;aarch64;Fail -mod;int;32;8;address;aarch64;Fail -mod;int;32;16;address;aarch64;Fail -mod;int;32;32;address;aarch64;Fail -mod;int;32;64;address;aarch64;Fail -mod;int;32;128;address;aarch64;Fail -mod;int;64;1;address;aarch64;Fail -mod;int;64;2;address;aarch64;Fail -mod;int;64;4;address;aarch64;Fail -mod;int;64;8;address;aarch64;Fail -mod;int;64;16;address;aarch64;Fail -mod;int;64;32;address;aarch64;Fail -mod;int;64;64;address;aarch64;Fail -mod;int;64;128;address;aarch64;Fail -or;int;8;1;address;aarch64;Fail -or;int;8;2;address;aarch64;Fail -or;int;8;4;address;aarch64;Fail -or;int;8;8;address;aarch64;Success; -or;int;8;16;address;aarch64;Success; -or;int;8;32;address;aarch64;Fail -or;int;8;64;address;aarch64;Fail -or;int;8;128;address;aarch64;Fail -or;int;16;1;address;aarch64;Fail -or;int;16;2;address;aarch64;Fail -or;int;16;4;address;aarch64;Success; -or;int;16;8;address;aarch64;Success; -or;int;16;16;address;aarch64;Fail -or;int;16;32;address;aarch64;Fail -or;int;16;64;address;aarch64;Fail -or;int;16;128;address;aarch64;Fail -or;int;32;1;address;aarch64;Fail -or;int;32;2;address;aarch64;Success; -or;int;32;4;address;aarch64;Success; -or;int;32;8;address;aarch64;Fail -or;int;32;16;address;aarch64;Fail -or;int;32;32;address;aarch64;Fail -or;int;32;64;address;aarch64;Fail -or;int;32;128;address;aarch64;Fail -or;int;64;1;address;aarch64;Fail -or;int;64;2;address;aarch64;Fail -or;int;64;4;address;aarch64;Fail -or;int;64;8;address;aarch64;Fail -or;int;64;16;address;aarch64;Fail -or;int;64;32;address;aarch64;Fail -or;int;64;64;address;aarch64;Fail -or;int;64;128;address;aarch64;Fail -and;int;8;1;address;aarch64;Fail -and;int;8;2;address;aarch64;Fail -and;int;8;4;address;aarch64;Fail -and;int;8;8;address;aarch64;Success; -and;int;8;16;address;aarch64;Success; -and;int;8;32;address;aarch64;Fail -and;int;8;64;address;aarch64;Fail -and;int;8;128;address;aarch64;Fail -and;int;16;1;address;aarch64;Fail -and;int;16;2;address;aarch64;Fail -and;int;16;4;address;aarch64;Success; -and;int;16;8;address;aarch64;Success; -and;int;16;16;address;aarch64;Fail -and;int;16;32;address;aarch64;Fail -and;int;16;64;address;aarch64;Fail -and;int;16;128;address;aarch64;Fail -and;int;32;1;address;aarch64;Fail -and;int;32;2;address;aarch64;Success; -and;int;32;4;address;aarch64;Success; -and;int;32;8;address;aarch64;Fail -and;int;32;16;address;aarch64;Fail -and;int;32;32;address;aarch64;Fail -and;int;32;64;address;aarch64;Fail -and;int;32;128;address;aarch64;Fail -and;int;64;1;address;aarch64;Fail -and;int;64;2;address;aarch64;Fail -and;int;64;4;address;aarch64;Fail -and;int;64;8;address;aarch64;Fail -and;int;64;16;address;aarch64;Fail -and;int;64;32;address;aarch64;Fail -and;int;64;64;address;aarch64;Fail -and;int;64;128;address;aarch64;Fail -xor;int;8;1;address;aarch64;Fail -xor;int;8;2;address;aarch64;Fail -xor;int;8;4;address;aarch64;Fail -xor;int;8;8;address;aarch64;Success; -xor;int;8;16;address;aarch64;Success; -xor;int;8;32;address;aarch64;Fail -xor;int;8;64;address;aarch64;Fail -xor;int;8;128;address;aarch64;Fail -xor;int;16;1;address;aarch64;Fail -xor;int;16;2;address;aarch64;Fail -xor;int;16;4;address;aarch64;Success; -xor;int;16;8;address;aarch64;Success; -xor;int;16;16;address;aarch64;Fail -xor;int;16;32;address;aarch64;Fail -xor;int;16;64;address;aarch64;Fail -xor;int;16;128;address;aarch64;Fail -xor;int;32;1;address;aarch64;Fail -xor;int;32;2;address;aarch64;Success; -xor;int;32;4;address;aarch64;Success; -xor;int;32;8;address;aarch64;Fail -xor;int;32;16;address;aarch64;Fail -xor;int;32;32;address;aarch64;Fail -xor;int;32;64;address;aarch64;Fail -xor;int;32;128;address;aarch64;Fail -xor;int;64;1;address;aarch64;Fail -xor;int;64;2;address;aarch64;Fail -xor;int;64;4;address;aarch64;Fail -xor;int;64;8;address;aarch64;Fail -xor;int;64;16;address;aarch64;Fail -xor;int;64;32;address;aarch64;Fail -xor;int;64;64;address;aarch64;Fail -xor;int;64;128;address;aarch64;Fail -sl;int;8;1;address;aarch64;Fail -sl;int;8;2;address;aarch64;Fail -sl;int;8;4;address;aarch64;Fail -sl;int;8;8;address;aarch64;Fail -sl;int;8;16;address;aarch64;Fail -sl;int;8;32;address;aarch64;Fail -sl;int;8;64;address;aarch64;Fail -sl;int;8;128;address;aarch64;Fail -sl;int;16;1;address;aarch64;Fail -sl;int;16;2;address;aarch64;Fail -sl;int;16;4;address;aarch64;Fail -sl;int;16;8;address;aarch64;Fail -sl;int;16;16;address;aarch64;Fail -sl;int;16;32;address;aarch64;Fail -sl;int;16;64;address;aarch64;Fail -sl;int;16;128;address;aarch64;Fail -sl;int;32;1;address;aarch64;Fail -sl;int;32;2;address;aarch64;Fail -sl;int;32;4;address;aarch64;Fail -sl;int;32;8;address;aarch64;Fail -sl;int;32;16;address;aarch64;Fail -sl;int;32;32;address;aarch64;Fail -sl;int;32;64;address;aarch64;Fail -sl;int;32;128;address;aarch64;Fail -sl;int;64;1;address;aarch64;Fail -sl;int;64;2;address;aarch64;Fail -sl;int;64;4;address;aarch64;Fail -sl;int;64;8;address;aarch64;Fail -sl;int;64;16;address;aarch64;Fail -sl;int;64;32;address;aarch64;Fail -sl;int;64;64;address;aarch64;Fail -sl;int;64;128;address;aarch64;Fail -sr;int;8;1;address;aarch64;Fail -sr;int;8;2;address;aarch64;Fail -sr;int;8;4;address;aarch64;Fail -sr;int;8;8;address;aarch64;Fail -sr;int;8;16;address;aarch64;Fail -sr;int;8;32;address;aarch64;Fail -sr;int;8;64;address;aarch64;Fail -sr;int;8;128;address;aarch64;Fail -sr;int;16;1;address;aarch64;Fail -sr;int;16;2;address;aarch64;Fail -sr;int;16;4;address;aarch64;Fail -sr;int;16;8;address;aarch64;Fail -sr;int;16;16;address;aarch64;Fail -sr;int;16;32;address;aarch64;Fail -sr;int;16;64;address;aarch64;Fail -sr;int;16;128;address;aarch64;Fail -sr;int;32;1;address;aarch64;Fail -sr;int;32;2;address;aarch64;Fail -sr;int;32;4;address;aarch64;Fail -sr;int;32;8;address;aarch64;Fail -sr;int;32;16;address;aarch64;Fail -sr;int;32;32;address;aarch64;Fail -sr;int;32;64;address;aarch64;Fail -sr;int;32;128;address;aarch64;Fail -sr;int;64;1;address;aarch64;Fail -sr;int;64;2;address;aarch64;Fail -sr;int;64;4;address;aarch64;Fail -sr;int;64;8;address;aarch64;Fail -sr;int;64;16;address;aarch64;Fail -sr;int;64;32;address;aarch64;Fail -sr;int;64;64;address;aarch64;Fail -sr;int;64;128;address;aarch64;Fail -add;int;8;1;address;riscv;Fail -add;int;8;2;address;riscv;Fail -add;int;8;4;address;riscv;Fail -add;int;8;8;address;riscv;Fail -add;int;8;16;address;riscv;Fail -add;int;8;32;address;riscv;Fail -add;int;8;64;address;riscv;Fail -add;int;8;128;address;riscv;Fail -add;int;16;1;address;riscv;Fail -add;int;16;2;address;riscv;Fail -add;int;16;4;address;riscv;Fail -add;int;16;8;address;riscv;Fail -add;int;16;16;address;riscv;Fail -add;int;16;32;address;riscv;Fail -add;int;16;64;address;riscv;Fail -add;int;16;128;address;riscv;Fail -add;int;32;1;address;riscv;Fail -add;int;32;2;address;riscv;Fail -add;int;32;4;address;riscv;Fail -add;int;32;8;address;riscv;Fail -add;int;32;16;address;riscv;Fail -add;int;32;32;address;riscv;Fail -add;int;32;64;address;riscv;Fail -add;int;32;128;address;riscv;Fail -add;int;64;1;address;riscv;Fail -add;int;64;2;address;riscv;Fail -add;int;64;4;address;riscv;Fail -add;int;64;8;address;riscv;Fail -add;int;64;16;address;riscv;Fail -add;int;64;32;address;riscv;Fail -add;int;64;64;address;riscv;Fail -add;int;64;128;address;riscv;Fail -mul;int;8;1;address;riscv;Fail -mul;int;8;2;address;riscv;Fail -mul;int;8;4;address;riscv;Fail -mul;int;8;8;address;riscv;Fail -mul;int;8;16;address;riscv;Fail -mul;int;8;32;address;riscv;Fail -mul;int;8;64;address;riscv;Fail -mul;int;8;128;address;riscv;Fail -mul;int;16;1;address;riscv;Fail -mul;int;16;2;address;riscv;Fail -mul;int;16;4;address;riscv;Fail -mul;int;16;8;address;riscv;Fail -mul;int;16;16;address;riscv;Fail -mul;int;16;32;address;riscv;Fail -mul;int;16;64;address;riscv;Fail -mul;int;16;128;address;riscv;Fail -mul;int;32;1;address;riscv;Fail -mul;int;32;2;address;riscv;Fail -mul;int;32;4;address;riscv;Fail -mul;int;32;8;address;riscv;Fail -mul;int;32;16;address;riscv;Fail -mul;int;32;32;address;riscv;Fail -mul;int;32;64;address;riscv;Fail -mul;int;32;128;address;riscv;Fail -mul;int;64;1;address;riscv;Fail -mul;int;64;2;address;riscv;Fail -mul;int;64;4;address;riscv;Fail -mul;int;64;8;address;riscv;Fail -mul;int;64;16;address;riscv;Fail -mul;int;64;32;address;riscv;Fail -mul;int;64;64;address;riscv;Fail -mul;int;64;128;address;riscv;Fail -sub;int;8;1;address;riscv;Fail -sub;int;8;2;address;riscv;Fail -sub;int;8;4;address;riscv;Fail -sub;int;8;8;address;riscv;Fail -sub;int;8;16;address;riscv;Fail -sub;int;8;32;address;riscv;Fail -sub;int;8;64;address;riscv;Fail -sub;int;8;128;address;riscv;Fail -sub;int;16;1;address;riscv;Fail -sub;int;16;2;address;riscv;Fail -sub;int;16;4;address;riscv;Fail -sub;int;16;8;address;riscv;Fail -sub;int;16;16;address;riscv;Fail -sub;int;16;32;address;riscv;Fail -sub;int;16;64;address;riscv;Fail -sub;int;16;128;address;riscv;Fail -sub;int;32;1;address;riscv;Fail -sub;int;32;2;address;riscv;Fail -sub;int;32;4;address;riscv;Fail -sub;int;32;8;address;riscv;Fail -sub;int;32;16;address;riscv;Fail -sub;int;32;32;address;riscv;Fail -sub;int;32;64;address;riscv;Fail -sub;int;32;128;address;riscv;Fail -sub;int;64;1;address;riscv;Fail -sub;int;64;2;address;riscv;Fail -sub;int;64;4;address;riscv;Fail -sub;int;64;8;address;riscv;Fail -sub;int;64;16;address;riscv;Fail -sub;int;64;32;address;riscv;Fail -sub;int;64;64;address;riscv;Fail -sub;int;64;128;address;riscv;Fail -div;int;8;1;address;riscv;Fail -div;int;8;2;address;riscv;Fail -div;int;8;4;address;riscv;Fail -div;int;8;8;address;riscv;Fail -div;int;8;16;address;riscv;Fail -div;int;8;32;address;riscv;Fail -div;int;8;64;address;riscv;Fail -div;int;8;128;address;riscv;Fail -div;int;16;1;address;riscv;Fail -div;int;16;2;address;riscv;Fail -div;int;16;4;address;riscv;Fail -div;int;16;8;address;riscv;Fail -div;int;16;16;address;riscv;Fail -div;int;16;32;address;riscv;Fail -div;int;16;64;address;riscv;Fail -div;int;16;128;address;riscv;Fail -div;int;32;1;address;riscv;Fail -div;int;32;2;address;riscv;Fail -div;int;32;4;address;riscv;Fail -div;int;32;8;address;riscv;Fail -div;int;32;16;address;riscv;Fail -div;int;32;32;address;riscv;Fail -div;int;32;64;address;riscv;Fail -div;int;32;128;address;riscv;Fail -div;int;64;1;address;riscv;Fail -div;int;64;2;address;riscv;Fail -div;int;64;4;address;riscv;Fail -div;int;64;8;address;riscv;Fail -div;int;64;16;address;riscv;Fail -div;int;64;32;address;riscv;Fail -div;int;64;64;address;riscv;Fail -div;int;64;128;address;riscv;Fail -add;flt;32;1;address;riscv;Fail -add;flt;32;2;address;riscv;Fail -add;flt;32;4;address;riscv;Fail -add;flt;32;8;address;riscv;Fail -add;flt;32;16;address;riscv;Fail -add;flt;32;32;address;riscv;Fail -add;flt;32;64;address;riscv;Fail -add;flt;32;128;address;riscv;Fail -add;flt;64;1;address;riscv;Fail -add;flt;64;2;address;riscv;Fail -add;flt;64;4;address;riscv;Fail -add;flt;64;8;address;riscv;Fail -add;flt;64;16;address;riscv;Fail -add;flt;64;32;address;riscv;Fail -add;flt;64;64;address;riscv;Fail -add;flt;64;128;address;riscv;Fail -mul;flt;32;1;address;riscv;Fail -mul;flt;32;2;address;riscv;Fail -mul;flt;32;4;address;riscv;Fail -mul;flt;32;8;address;riscv;Fail -mul;flt;32;16;address;riscv;Fail -mul;flt;32;32;address;riscv;Fail -mul;flt;32;64;address;riscv;Fail -mul;flt;32;128;address;riscv;Fail -mul;flt;64;1;address;riscv;Fail -mul;flt;64;2;address;riscv;Fail -mul;flt;64;4;address;riscv;Fail -mul;flt;64;8;address;riscv;Fail -mul;flt;64;16;address;riscv;Fail -mul;flt;64;32;address;riscv;Fail -mul;flt;64;64;address;riscv;Fail -mul;flt;64;128;address;riscv;Fail -sub;flt;32;1;address;riscv;Fail -sub;flt;32;2;address;riscv;Fail -sub;flt;32;4;address;riscv;Fail -sub;flt;32;8;address;riscv;Fail -sub;flt;32;16;address;riscv;Fail -sub;flt;32;32;address;riscv;Fail -sub;flt;32;64;address;riscv;Fail -sub;flt;32;128;address;riscv;Fail -sub;flt;64;1;address;riscv;Fail -sub;flt;64;2;address;riscv;Fail -sub;flt;64;4;address;riscv;Fail -sub;flt;64;8;address;riscv;Fail -sub;flt;64;16;address;riscv;Fail -sub;flt;64;32;address;riscv;Fail -sub;flt;64;64;address;riscv;Fail -sub;flt;64;128;address;riscv;Fail -div;flt;32;1;address;riscv;Fail -div;flt;32;2;address;riscv;Fail -div;flt;32;4;address;riscv;Fail -div;flt;32;8;address;riscv;Fail -div;flt;32;16;address;riscv;Fail -div;flt;32;32;address;riscv;Fail -div;flt;32;64;address;riscv;Fail -div;flt;32;128;address;riscv;Fail -div;flt;64;1;address;riscv;Fail -div;flt;64;2;address;riscv;Fail -div;flt;64;4;address;riscv;Fail -div;flt;64;8;address;riscv;Fail -div;flt;64;16;address;riscv;Fail -div;flt;64;32;address;riscv;Fail -div;flt;64;64;address;riscv;Fail -div;flt;64;128;address;riscv;Fail -mod;int;8;1;address;riscv;Fail -mod;int;8;2;address;riscv;Fail -mod;int;8;4;address;riscv;Fail -mod;int;8;8;address;riscv;Fail -mod;int;8;16;address;riscv;Fail -mod;int;8;32;address;riscv;Fail -mod;int;8;64;address;riscv;Fail -mod;int;8;128;address;riscv;Fail -mod;int;16;1;address;riscv;Fail -mod;int;16;2;address;riscv;Fail -mod;int;16;4;address;riscv;Fail -mod;int;16;8;address;riscv;Fail -mod;int;16;16;address;riscv;Fail -mod;int;16;32;address;riscv;Fail -mod;int;16;64;address;riscv;Fail -mod;int;16;128;address;riscv;Fail -mod;int;32;1;address;riscv;Fail -mod;int;32;2;address;riscv;Fail -mod;int;32;4;address;riscv;Fail -mod;int;32;8;address;riscv;Fail -mod;int;32;16;address;riscv;Fail -mod;int;32;32;address;riscv;Fail -mod;int;32;64;address;riscv;Fail -mod;int;32;128;address;riscv;Fail -mod;int;64;1;address;riscv;Fail -mod;int;64;2;address;riscv;Fail -mod;int;64;4;address;riscv;Fail -mod;int;64;8;address;riscv;Fail -mod;int;64;16;address;riscv;Fail -mod;int;64;32;address;riscv;Fail -mod;int;64;64;address;riscv;Fail -mod;int;64;128;address;riscv;Fail -or;int;8;1;address;riscv;Fail -or;int;8;2;address;riscv;Fail -or;int;8;4;address;riscv;Fail -or;int;8;8;address;riscv;Fail -or;int;8;16;address;riscv;Fail -or;int;8;32;address;riscv;Fail -or;int;8;64;address;riscv;Fail -or;int;8;128;address;riscv;Fail -or;int;16;1;address;riscv;Fail -or;int;16;2;address;riscv;Fail -or;int;16;4;address;riscv;Fail -or;int;16;8;address;riscv;Fail -or;int;16;16;address;riscv;Fail -or;int;16;32;address;riscv;Fail -or;int;16;64;address;riscv;Fail -or;int;16;128;address;riscv;Fail -or;int;32;1;address;riscv;Fail -or;int;32;2;address;riscv;Fail -or;int;32;4;address;riscv;Fail -or;int;32;8;address;riscv;Fail -or;int;32;16;address;riscv;Fail -or;int;32;32;address;riscv;Fail -or;int;32;64;address;riscv;Fail -or;int;32;128;address;riscv;Fail -or;int;64;1;address;riscv;Fail -or;int;64;2;address;riscv;Fail -or;int;64;4;address;riscv;Fail -or;int;64;8;address;riscv;Fail -or;int;64;16;address;riscv;Fail -or;int;64;32;address;riscv;Fail -or;int;64;64;address;riscv;Fail -or;int;64;128;address;riscv;Fail -and;int;8;1;address;riscv;Fail -and;int;8;2;address;riscv;Fail -and;int;8;4;address;riscv;Fail -and;int;8;8;address;riscv;Fail -and;int;8;16;address;riscv;Fail -and;int;8;32;address;riscv;Fail -and;int;8;64;address;riscv;Fail -and;int;8;128;address;riscv;Fail -and;int;16;1;address;riscv;Fail -and;int;16;2;address;riscv;Fail -and;int;16;4;address;riscv;Fail -and;int;16;8;address;riscv;Fail -and;int;16;16;address;riscv;Fail -and;int;16;32;address;riscv;Fail -and;int;16;64;address;riscv;Fail -and;int;16;128;address;riscv;Fail -and;int;32;1;address;riscv;Fail -and;int;32;2;address;riscv;Fail -and;int;32;4;address;riscv;Fail -and;int;32;8;address;riscv;Fail -and;int;32;16;address;riscv;Fail -and;int;32;32;address;riscv;Fail -and;int;32;64;address;riscv;Fail -and;int;32;128;address;riscv;Fail -and;int;64;1;address;riscv;Fail -and;int;64;2;address;riscv;Fail -and;int;64;4;address;riscv;Fail -and;int;64;8;address;riscv;Fail -and;int;64;16;address;riscv;Fail -and;int;64;32;address;riscv;Fail -and;int;64;64;address;riscv;Fail -and;int;64;128;address;riscv;Fail -xor;int;8;1;address;riscv;Fail -xor;int;8;2;address;riscv;Fail -xor;int;8;4;address;riscv;Fail -xor;int;8;8;address;riscv;Fail -xor;int;8;16;address;riscv;Fail -xor;int;8;32;address;riscv;Fail -xor;int;8;64;address;riscv;Fail -xor;int;8;128;address;riscv;Fail -xor;int;16;1;address;riscv;Fail -xor;int;16;2;address;riscv;Fail -xor;int;16;4;address;riscv;Fail -xor;int;16;8;address;riscv;Fail -xor;int;16;16;address;riscv;Fail -xor;int;16;32;address;riscv;Fail -xor;int;16;64;address;riscv;Fail -xor;int;16;128;address;riscv;Fail -xor;int;32;1;address;riscv;Fail -xor;int;32;2;address;riscv;Fail -xor;int;32;4;address;riscv;Fail -xor;int;32;8;address;riscv;Fail -xor;int;32;16;address;riscv;Fail -xor;int;32;32;address;riscv;Fail -xor;int;32;64;address;riscv;Fail -xor;int;32;128;address;riscv;Fail -xor;int;64;1;address;riscv;Fail -xor;int;64;2;address;riscv;Fail -xor;int;64;4;address;riscv;Fail -xor;int;64;8;address;riscv;Fail -xor;int;64;16;address;riscv;Fail -xor;int;64;32;address;riscv;Fail -xor;int;64;64;address;riscv;Fail -xor;int;64;128;address;riscv;Fail -sl;int;8;1;address;riscv;Fail -sl;int;8;2;address;riscv;Fail -sl;int;8;4;address;riscv;Fail -sl;int;8;8;address;riscv;Fail -sl;int;8;16;address;riscv;Fail -sl;int;8;32;address;riscv;Fail -sl;int;8;64;address;riscv;Fail -sl;int;8;128;address;riscv;Fail -sl;int;16;1;address;riscv;Fail -sl;int;16;2;address;riscv;Fail -sl;int;16;4;address;riscv;Fail -sl;int;16;8;address;riscv;Fail -sl;int;16;16;address;riscv;Fail -sl;int;16;32;address;riscv;Fail -sl;int;16;64;address;riscv;Fail -sl;int;16;128;address;riscv;Fail -sl;int;32;1;address;riscv;Fail -sl;int;32;2;address;riscv;Fail -sl;int;32;4;address;riscv;Fail -sl;int;32;8;address;riscv;Fail -sl;int;32;16;address;riscv;Fail -sl;int;32;32;address;riscv;Fail -sl;int;32;64;address;riscv;Fail -sl;int;32;128;address;riscv;Fail -sl;int;64;1;address;riscv;Fail -sl;int;64;2;address;riscv;Fail -sl;int;64;4;address;riscv;Fail -sl;int;64;8;address;riscv;Fail -sl;int;64;16;address;riscv;Fail -sl;int;64;32;address;riscv;Fail -sl;int;64;64;address;riscv;Fail -sl;int;64;128;address;riscv;Fail -sr;int;8;1;address;riscv;Fail -sr;int;8;2;address;riscv;Fail -sr;int;8;4;address;riscv;Fail -sr;int;8;8;address;riscv;Fail -sr;int;8;16;address;riscv;Fail -sr;int;8;32;address;riscv;Fail -sr;int;8;64;address;riscv;Fail -sr;int;8;128;address;riscv;Fail -sr;int;16;1;address;riscv;Fail -sr;int;16;2;address;riscv;Fail -sr;int;16;4;address;riscv;Fail -sr;int;16;8;address;riscv;Fail -sr;int;16;16;address;riscv;Fail -sr;int;16;32;address;riscv;Fail -sr;int;16;64;address;riscv;Fail -sr;int;16;128;address;riscv;Fail -sr;int;32;1;address;riscv;Fail -sr;int;32;2;address;riscv;Fail -sr;int;32;4;address;riscv;Fail -sr;int;32;8;address;riscv;Fail -sr;int;32;16;address;riscv;Fail -sr;int;32;32;address;riscv;Fail -sr;int;32;64;address;riscv;Fail -sr;int;32;128;address;riscv;Fail -sr;int;64;1;address;riscv;Fail -sr;int;64;2;address;riscv;Fail -sr;int;64;4;address;riscv;Fail -sr;int;64;8;address;riscv;Fail -sr;int;64;16;address;riscv;Fail -sr;int;64;32;address;riscv;Fail -sr;int;64;64;address;riscv;Fail -sr;int;64;128;address;riscv;Fail -add;int;8;1;address;power;Fail -add;int;8;2;address;power;Fail -add;int;8;4;address;power;Fail -add;int;8;8;address;power;Fail -add;int;8;16;address;power;Fail -add;int;8;32;address;power;Fail -add;int;8;64;address;power;Fail -add;int;8;128;address;power;Fail -add;int;16;1;address;power;Fail -add;int;16;2;address;power;Fail -add;int;16;4;address;power;Fail -add;int;16;8;address;power;Fail -add;int;16;16;address;power;Fail -add;int;16;32;address;power;Fail -add;int;16;64;address;power;Fail -add;int;16;128;address;power;Fail -add;int;32;1;address;power;Fail -add;int;32;2;address;power;Fail -add;int;32;4;address;power;Fail -add;int;32;8;address;power;Fail -add;int;32;16;address;power;Fail -add;int;32;32;address;power;Fail -add;int;32;64;address;power;Fail -add;int;32;128;address;power;Fail -add;int;64;1;address;power;Fail -add;int;64;2;address;power;Fail -add;int;64;4;address;power;Fail -add;int;64;8;address;power;Fail -add;int;64;16;address;power;Fail -add;int;64;32;address;power;Fail -add;int;64;64;address;power;Fail -add;int;64;128;address;power;Fail -mul;int;8;1;address;power;Fail -mul;int;8;2;address;power;Fail -mul;int;8;4;address;power;Fail -mul;int;8;8;address;power;Fail -mul;int;8;16;address;power;Fail -mul;int;8;32;address;power;Fail -mul;int;8;64;address;power;Fail -mul;int;8;128;address;power;Fail -mul;int;16;1;address;power;Fail -mul;int;16;2;address;power;Fail -mul;int;16;4;address;power;Fail -mul;int;16;8;address;power;Fail -mul;int;16;16;address;power;Fail -mul;int;16;32;address;power;Fail -mul;int;16;64;address;power;Fail -mul;int;16;128;address;power;Fail -mul;int;32;1;address;power;Fail -mul;int;32;2;address;power;Fail -mul;int;32;4;address;power;Fail -mul;int;32;8;address;power;Fail -mul;int;32;16;address;power;Fail -mul;int;32;32;address;power;Fail -mul;int;32;64;address;power;Fail -mul;int;32;128;address;power;Fail -mul;int;64;1;address;power;Fail -mul;int;64;2;address;power;Fail -mul;int;64;4;address;power;Fail -mul;int;64;8;address;power;Fail -mul;int;64;16;address;power;Fail -mul;int;64;32;address;power;Fail -mul;int;64;64;address;power;Fail -mul;int;64;128;address;power;Fail -sub;int;8;1;address;power;Fail -sub;int;8;2;address;power;Fail -sub;int;8;4;address;power;Fail -sub;int;8;8;address;power;Fail -sub;int;8;16;address;power;Fail -sub;int;8;32;address;power;Fail -sub;int;8;64;address;power;Fail -sub;int;8;128;address;power;Fail -sub;int;16;1;address;power;Fail -sub;int;16;2;address;power;Fail -sub;int;16;4;address;power;Fail -sub;int;16;8;address;power;Fail -sub;int;16;16;address;power;Fail -sub;int;16;32;address;power;Fail -sub;int;16;64;address;power;Fail -sub;int;16;128;address;power;Fail -sub;int;32;1;address;power;Fail -sub;int;32;2;address;power;Fail -sub;int;32;4;address;power;Fail -sub;int;32;8;address;power;Fail -sub;int;32;16;address;power;Fail -sub;int;32;32;address;power;Fail -sub;int;32;64;address;power;Fail -sub;int;32;128;address;power;Fail -sub;int;64;1;address;power;Fail -sub;int;64;2;address;power;Fail -sub;int;64;4;address;power;Fail -sub;int;64;8;address;power;Fail -sub;int;64;16;address;power;Fail -sub;int;64;32;address;power;Fail -sub;int;64;64;address;power;Fail -sub;int;64;128;address;power;Fail -div;int;8;1;address;power;Fail -div;int;8;2;address;power;Fail -div;int;8;4;address;power;Fail -div;int;8;8;address;power;Fail -div;int;8;16;address;power;Fail -div;int;8;32;address;power;Fail -div;int;8;64;address;power;Fail -div;int;8;128;address;power;Fail -div;int;16;1;address;power;Fail -div;int;16;2;address;power;Fail -div;int;16;4;address;power;Fail -div;int;16;8;address;power;Fail -div;int;16;16;address;power;Fail -div;int;16;32;address;power;Fail -div;int;16;64;address;power;Fail -div;int;16;128;address;power;Fail -div;int;32;1;address;power;Fail -div;int;32;2;address;power;Fail -div;int;32;4;address;power;Fail -div;int;32;8;address;power;Fail -div;int;32;16;address;power;Fail -div;int;32;32;address;power;Fail -div;int;32;64;address;power;Fail -div;int;32;128;address;power;Fail -div;int;64;1;address;power;Fail -div;int;64;2;address;power;Fail -div;int;64;4;address;power;Fail -div;int;64;8;address;power;Fail -div;int;64;16;address;power;Fail -div;int;64;32;address;power;Fail -div;int;64;64;address;power;Fail -div;int;64;128;address;power;Fail -add;flt;32;1;address;power;Fail -add;flt;32;2;address;power;Fail -add;flt;32;4;address;power;Fail -add;flt;32;8;address;power;Fail -add;flt;32;16;address;power;Fail -add;flt;32;32;address;power;Fail -add;flt;32;64;address;power;Fail -add;flt;32;128;address;power;Fail -add;flt;64;1;address;power;Fail -add;flt;64;2;address;power;Fail -add;flt;64;4;address;power;Fail -add;flt;64;8;address;power;Fail -add;flt;64;16;address;power;Fail -add;flt;64;32;address;power;Fail -add;flt;64;64;address;power;Fail -add;flt;64;128;address;power;Fail -mul;flt;32;1;address;power;Fail -mul;flt;32;2;address;power;Fail -mul;flt;32;4;address;power;Fail -mul;flt;32;8;address;power;Fail -mul;flt;32;16;address;power;Fail -mul;flt;32;32;address;power;Fail -mul;flt;32;64;address;power;Fail -mul;flt;32;128;address;power;Fail -mul;flt;64;1;address;power;Fail -mul;flt;64;2;address;power;Fail -mul;flt;64;4;address;power;Fail -mul;flt;64;8;address;power;Fail -mul;flt;64;16;address;power;Fail -mul;flt;64;32;address;power;Fail -mul;flt;64;64;address;power;Fail -mul;flt;64;128;address;power;Fail -sub;flt;32;1;address;power;Fail -sub;flt;32;2;address;power;Fail -sub;flt;32;4;address;power;Fail -sub;flt;32;8;address;power;Fail -sub;flt;32;16;address;power;Fail -sub;flt;32;32;address;power;Fail -sub;flt;32;64;address;power;Fail -sub;flt;32;128;address;power;Fail -sub;flt;64;1;address;power;Fail -sub;flt;64;2;address;power;Fail -sub;flt;64;4;address;power;Fail -sub;flt;64;8;address;power;Fail -sub;flt;64;16;address;power;Fail -sub;flt;64;32;address;power;Fail -sub;flt;64;64;address;power;Fail -sub;flt;64;128;address;power;Fail -div;flt;32;1;address;power;Fail -div;flt;32;2;address;power;Fail -div;flt;32;4;address;power;Fail -div;flt;32;8;address;power;Fail -div;flt;32;16;address;power;Fail -div;flt;32;32;address;power;Fail -div;flt;32;64;address;power;Fail -div;flt;32;128;address;power;Fail -div;flt;64;1;address;power;Fail -div;flt;64;2;address;power;Fail -div;flt;64;4;address;power;Fail -div;flt;64;8;address;power;Fail -div;flt;64;16;address;power;Fail -div;flt;64;32;address;power;Fail -div;flt;64;64;address;power;Fail -div;flt;64;128;address;power;Fail -mod;int;8;1;address;power;Fail -mod;int;8;2;address;power;Fail -mod;int;8;4;address;power;Fail -mod;int;8;8;address;power;Fail -mod;int;8;16;address;power;Fail -mod;int;8;32;address;power;Fail -mod;int;8;64;address;power;Fail -mod;int;8;128;address;power;Fail -mod;int;16;1;address;power;Fail -mod;int;16;2;address;power;Fail -mod;int;16;4;address;power;Fail -mod;int;16;8;address;power;Fail -mod;int;16;16;address;power;Fail -mod;int;16;32;address;power;Fail -mod;int;16;64;address;power;Fail -mod;int;16;128;address;power;Fail -mod;int;32;1;address;power;Fail -mod;int;32;2;address;power;Fail -mod;int;32;4;address;power;Fail -mod;int;32;8;address;power;Fail -mod;int;32;16;address;power;Fail -mod;int;32;32;address;power;Fail -mod;int;32;64;address;power;Fail -mod;int;32;128;address;power;Fail -mod;int;64;1;address;power;Fail -mod;int;64;2;address;power;Fail -mod;int;64;4;address;power;Fail -mod;int;64;8;address;power;Fail -mod;int;64;16;address;power;Fail -mod;int;64;32;address;power;Fail -mod;int;64;64;address;power;Fail -mod;int;64;128;address;power;Fail -or;int;8;1;address;power;Fail -or;int;8;2;address;power;Fail -or;int;8;4;address;power;Fail -or;int;8;8;address;power;Fail -or;int;8;16;address;power;Fail -or;int;8;32;address;power;Fail -or;int;8;64;address;power;Fail -or;int;8;128;address;power;Fail -or;int;16;1;address;power;Fail -or;int;16;2;address;power;Fail -or;int;16;4;address;power;Fail -or;int;16;8;address;power;Fail -or;int;16;16;address;power;Fail -or;int;16;32;address;power;Fail -or;int;16;64;address;power;Fail -or;int;16;128;address;power;Fail -or;int;32;1;address;power;Fail -or;int;32;2;address;power;Fail -or;int;32;4;address;power;Fail -or;int;32;8;address;power;Fail -or;int;32;16;address;power;Fail -or;int;32;32;address;power;Fail -or;int;32;64;address;power;Fail -or;int;32;128;address;power;Fail -or;int;64;1;address;power;Fail -or;int;64;2;address;power;Fail -or;int;64;4;address;power;Fail -or;int;64;8;address;power;Fail -or;int;64;16;address;power;Fail -or;int;64;32;address;power;Fail -or;int;64;64;address;power;Fail -or;int;64;128;address;power;Fail -and;int;8;1;address;power;Fail -and;int;8;2;address;power;Fail -and;int;8;4;address;power;Fail -and;int;8;8;address;power;Fail -and;int;8;16;address;power;Fail -and;int;8;32;address;power;Fail -and;int;8;64;address;power;Fail -and;int;8;128;address;power;Fail -and;int;16;1;address;power;Fail -and;int;16;2;address;power;Fail -and;int;16;4;address;power;Fail -and;int;16;8;address;power;Fail -and;int;16;16;address;power;Fail -and;int;16;32;address;power;Fail -and;int;16;64;address;power;Fail -and;int;16;128;address;power;Fail -and;int;32;1;address;power;Fail -and;int;32;2;address;power;Fail -and;int;32;4;address;power;Fail -and;int;32;8;address;power;Fail -and;int;32;16;address;power;Fail -and;int;32;32;address;power;Fail -and;int;32;64;address;power;Fail -and;int;32;128;address;power;Fail -and;int;64;1;address;power;Fail -and;int;64;2;address;power;Fail -and;int;64;4;address;power;Fail -and;int;64;8;address;power;Fail -and;int;64;16;address;power;Fail -and;int;64;32;address;power;Fail -and;int;64;64;address;power;Fail -and;int;64;128;address;power;Fail -xor;int;8;1;address;power;Fail -xor;int;8;2;address;power;Fail -xor;int;8;4;address;power;Fail -xor;int;8;8;address;power;Fail -xor;int;8;16;address;power;Fail -xor;int;8;32;address;power;Fail -xor;int;8;64;address;power;Fail -xor;int;8;128;address;power;Fail -xor;int;16;1;address;power;Fail -xor;int;16;2;address;power;Fail -xor;int;16;4;address;power;Fail -xor;int;16;8;address;power;Fail -xor;int;16;16;address;power;Fail -xor;int;16;32;address;power;Fail -xor;int;16;64;address;power;Fail -xor;int;16;128;address;power;Fail -xor;int;32;1;address;power;Fail -xor;int;32;2;address;power;Fail -xor;int;32;4;address;power;Fail -xor;int;32;8;address;power;Fail -xor;int;32;16;address;power;Fail -xor;int;32;32;address;power;Fail -xor;int;32;64;address;power;Fail -xor;int;32;128;address;power;Fail -xor;int;64;1;address;power;Fail -xor;int;64;2;address;power;Fail -xor;int;64;4;address;power;Fail -xor;int;64;8;address;power;Fail -xor;int;64;16;address;power;Fail -xor;int;64;32;address;power;Fail -xor;int;64;64;address;power;Fail -xor;int;64;128;address;power;Fail -sl;int;8;1;address;power;Fail -sl;int;8;2;address;power;Fail -sl;int;8;4;address;power;Fail -sl;int;8;8;address;power;Fail -sl;int;8;16;address;power;Fail -sl;int;8;32;address;power;Fail -sl;int;8;64;address;power;Fail -sl;int;8;128;address;power;Fail -sl;int;16;1;address;power;Fail -sl;int;16;2;address;power;Fail -sl;int;16;4;address;power;Fail -sl;int;16;8;address;power;Fail -sl;int;16;16;address;power;Fail -sl;int;16;32;address;power;Fail -sl;int;16;64;address;power;Fail -sl;int;16;128;address;power;Fail -sl;int;32;1;address;power;Fail -sl;int;32;2;address;power;Fail -sl;int;32;4;address;power;Fail -sl;int;32;8;address;power;Fail -sl;int;32;16;address;power;Fail -sl;int;32;32;address;power;Fail -sl;int;32;64;address;power;Fail -sl;int;32;128;address;power;Fail -sl;int;64;1;address;power;Fail -sl;int;64;2;address;power;Fail -sl;int;64;4;address;power;Fail -sl;int;64;8;address;power;Fail -sl;int;64;16;address;power;Fail -sl;int;64;32;address;power;Fail -sl;int;64;64;address;power;Fail -sl;int;64;128;address;power;Fail -sr;int;8;1;address;power;Fail -sr;int;8;2;address;power;Fail -sr;int;8;4;address;power;Fail -sr;int;8;8;address;power;Fail -sr;int;8;16;address;power;Fail -sr;int;8;32;address;power;Fail -sr;int;8;64;address;power;Fail -sr;int;8;128;address;power;Fail -sr;int;16;1;address;power;Fail -sr;int;16;2;address;power;Fail -sr;int;16;4;address;power;Fail -sr;int;16;8;address;power;Fail -sr;int;16;16;address;power;Fail -sr;int;16;32;address;power;Fail -sr;int;16;64;address;power;Fail -sr;int;16;128;address;power;Fail -sr;int;32;1;address;power;Fail -sr;int;32;2;address;power;Fail -sr;int;32;4;address;power;Fail -sr;int;32;8;address;power;Fail -sr;int;32;16;address;power;Fail -sr;int;32;32;address;power;Fail -sr;int;32;64;address;power;Fail -sr;int;32;128;address;power;Fail -sr;int;64;1;address;power;Fail -sr;int;64;2;address;power;Fail -sr;int;64;4;address;power;Fail -sr;int;64;8;address;power;Fail -sr;int;64;16;address;power;Fail -sr;int;64;32;address;power;Fail -sr;int;64;64;address;power;Fail -sr;int;64;128;address;power;Fail

+$RLX=hZ?m_$j|$umj6l1P<7}g(#^@m~oVU%zL)*pdKRomMt zhhclPa+uj}Q4W7geV05|0htQOR6yo1WDY~-Fg!~9QA&k2&Q*Z25CzYfl*4SCJB&MO z7)rcNzlr|>;{FB1{Y#KM|B}&$K->`^j@qs{#C;3IeG9~WD?m$GvK|KF4g+yyb!+@q zevD=-hhY05NLIl13fNu&+biHt)$$}O-#evFgR$h%#<9RS`A z0B;8b$#X!K#Dl=wLE!BmtZ5E!`+>Lpz}tR762F!u>({{B*TCD?t@YcneXzY8wwJ^9 za@bxD+sk2lIZ9G3_gBhcd8AU#ERRykzbBhXW-ny+LS`>y_CjVaWXj=B;+K@Y+6cE7 zR1{HcgxkwTxV>8m!R5E>H+MPkRt~&?9|3LqC%B2=C?4VjE!$) z?-PQ{Zr5+_UBKHe;BB`cS$E5ldpGd58+iModB1r|fwwZ?txS;IWwPWc1KxH4Z@VDZ zD!2d6Z?I8rCv3*A#0cTm%V_z_g5t9$4Z*D|=Y`d9+cNC`kduMqSVB0P7_o5+U4uNe=g1 z5+t!kmaH{Ggu6zjU*DUx#_EBb2XY?B?SR}4$nAjKj@DT7-o~o(ZY9hbiLA+71538S zl5MbL8!XudOSZw1Z77xW4^y@=Yy6dMpdyKaHBrhoU^80T22A`!rP0&4!0|Rh=`C!$ zspo}AJYk4u9p!MbR*I0u*flinc(5ZSWdlM^d&hBn2p2Kt&M+Bt~+`3he+*@VIvsH)?x5*J!!hdT+#A8Y5!{==y$Rf# zz)kmg;*3@{GPxjSBPf$57piPR9}ZJCp|70x_F+jOsm;)VO5Kc7H=|S<^R}Q=wFTQM zn^~#Q1}$h&HUsycqt|~19DW8Ieg+(F1`am^hxon2%p zlSZ552=Oz>-L$_n9j9$Gsso+%2qUKJ$wRax>}MGNC8 zX6vubYt?LTY_V1|PF8Js@;i8O18Um{FK&bvH==De!pj@sWwm8E)-s{gPVi`$vJv}c zl0xmd0WupPvjH+2AhQ878_+TvSW9kT?P^en3R6HqT2eNkT_cIwLL>DCbyV_v0zYho zA2z}d8{vnI@WZF@!>6d_ruN))zpa@*C2kPHtsCTU_Xa`oY>*}K6CuL-i5%hn1U0p; zPtgo>9jspm>({~hb+CRNtX~I@u4A@~$~xFCDWG6`q_PhCW>E^slt88gG9{2HflLWx zN}vJphbbjY+FvOF6-gANqm&YMR|7SPa9yI^&DH_e>wxQZf+Vh&CF^?NdOdKx{!V+& zU4ouaB8Q7>1-Gt(Uk&S5!}`^*el@ILjZ#YBQPuVUWi@P% zQdTqDqm|WI4_XwGDTYijWQrkE44KuCSq+a8f22~(Jl9q!1{F;dJZDjg;W-nP6=T2* zcD07N)xg{uU~Y{dx!1^&XALlir(&(t4tExF9|LnA19Kk>lILR?wgYpkfjP3dRhXOc z0jysM>sP}1m5?rm^~JEh7#>w^Z>Ow;?G|Mvv)!Z=W8W-PA&)JG%yP)Agv?6Ftc1); zc$D~~mF3KHLCSJaCQUk2S;I`ZXFt-YrTP2`YS+W)bbH%_MwZ|RxoO=Z@ zw*r`3DM;3pvgBR~%&i3GR<+i1Rd2!iWsq79>zBj&<*W!N{1LLT#*=OZ9) zIS{v8klf2<$+H}Y!>^>)6{zEm`b}I0#4Q8jmI;z)nJkGP0dXGzaUY?k)*!C@HTs2f zDQsT~+n2)jrLdjWnoHr&rOa|sSqjS~1r#igRF-1jEJ`7n#gJJHnZ=M<44K7{Squ$` zKTKK7r2Un}pdyKabd<7~jdF{zhh#yXinpb}+fv|dsUV3T%98a%;O#@;?ZZ3mH}_)T zZ87k+M3AgYWXZh*cv}LzEp4se>d(RUBG_I8+lyd(5o|9)DU0Dx)$#zP2$n}FMa=SO zrHI)~GK(Oy2r`Qxvj{RpkST&ci9b?V#QfG)Sp+JYDEQ5yEMj9^5yr_-l&IpZ2zdJd zc>6$*+#kr2=L6tvG4MuhaA)!MPvGsJa=81Sg5>$949kJHBH)cIZXMpff$fE`y%4q+ zLV6KwUj*A1!Jn$-?UX`TZcz%Eea zAt;k39jX+v5v~yXW)kvLyuB}kyWa=i-WO1(ELj%;Z;Rvz54FV|^_%-W;O#x&tx%Ax zg|g%>6e2u@z}x$+^;`XR*j@msg|K}gY+nf57sB?1@TY1y$1D#eKL9ad%0ld$NecO^ z05S!TDS%7?WC|ct0Dl%RPZcn~85E+z6i|?slma%s6=2^i3VABt-UZ$k0&fci$-PjP zJPU!h_kg$eP{$qhn^*w66##Dqg5)WXCGlP0?OovQUDVV%ywM$W0c>9Y+ZVw01+aYq zY+nF>E?}06$^uv}DWG6^q_P0}W>E^sZwr981;E<^K@#7QCF?uD+dIJ9J9pY|?tI`aA9$NDNY?qXnU=wWlw!>Em0<*ga-2$8q9YlRwr zV*ZR4XTpy&QS&VLaTfeI3+S5#KhI*G3{qyolO_ceJQ=FY0{3)q&jj~OaL)wyOmNRc zs}QF}na<=mCKsyAWO8B3OtgTc%%patwL053j8sT!7TS_ZorO~8pwu}ibq-2ZTe6)p zi(*oQ+bN*>mvB5W>Zoa=3M-Ah~DC zk_Q@zZ^;qXw;*@Zwr;ZLu%%0$u%!P~@?TYP{rRYzl{vx(lc&fZY@O1}xHzUyUa!af z`8B!gV%Fps`>*ppS44KxdkZ|%tBT*l(~+L({jz1#)`>#c4V2 zUC=4Kj=^_U?R)rI(R zF_6F$Sw(dM-i%RIek>2qlj6BKIYO+H@%{wpQuq2iJXu}~Ph5jXkn5?Vx=PETBhApL z+&Z+D0qJXa=A4@x-vRe^ydMF7kw|}yNbjx*?~%lXckh{O>SG#iPcel%@ot*%WW4JK z?|VT;suQokF|il!B)U>FGfZO=Q`79Yp2}XT)5qj}=MMNI)y#)Y0~wPkDKpt_O0j3y z9ZZ(J_2$_`M@DK!O0;Rja8qiA)8!bS#L8`8^H#wCrV6m*wgJ9 zF12Z#z?3P2YgyzKMe6O#4g0ei1QH-+*Dt`1#vRs zvxuuVqdvSdseBviL43(mUq21;&Yj>x{QKR|5AnJ^_4VEHzNVvl>+8oNUbMfyz7X-u zgZ1?lh&LjxMOL zC=Una#UNxMFAOmqCIot~*CgaUfS8L73XaV)44ljl-WppL8$?+oH-Q3pU>ZA2I8Q?u zgS^KmCpM^iY#txmE`UobYiH_-y5`#7ysPSoa8vdkJN<3lU84Vsu<$*m+ujj!Mtm`!hJjvj3sXRV< zjq&P5W#JW9Trv0tseHPPhJHTv%>mB=@QiB0^Nhwr_7SECV{b&}*1iE%u(j05pUPeAB2wVuObLnfy9Mm?h5kBku|h1LGeSyDN5o?AK&9z5frs z1AiGXTM6tzu9$BsxKm()#e9Qgcd$-?T-N9CsajvmAiX|TTd-PN43lAXk<4=Nj^0{d zUk;m4R}-0yJgdk@hV-k1Or6$eAX9#we*IMa%6;@BxqGQkp>I)Nypca%y@@}DLGINu zwQt`@F6bt5d63IMANHtz%xdb!WvZH44PI3JPksODm-Y1*ZldRb8`NilNi{N{n*Jn)+be)GU@9{7Lef$4a8wSrKA zKub${SGEa(-Y@?U#R&AS@c_`Y7eqAefwTindmKbl*noG*|58_<$rFHv%2B+~x)8k4>-3uB)%l zJcaV>5tGi3G>>S0UonbqBvNU1SBvwGT+>6AoyFQq0q9cp5X zJtN5uZe*sXk5B87MOy=`9aP<^C9t=Ewxl(zevn@coc?BgJy-R&fxXFGmD8_uMFQ_0 zW|_<)Dv)hV5fVsmev)A%qHc5{O2CWiRRO9rXe&e>Bqlm$A&7jy8sv!vpIq ziN+@>;{Dem@_PX%Ug}IcHKM_9H6p(yIPsAWgj4!WK!ty}QyS9kML)dvo%4I0E=S!% z`*LD{Uo@2!VC+MY=+^^Lu!wp$A>lUz!iL|4i~^^h4H?3{A^j=+Ax^@5oyZVBH>H2q ziQWqD_g^@PT{><>)S;dDgV-hrLIJBt_aDWeFOkg!>>%pAN{Imps6qTmr2@E)9}#&$ z6ut##8``A$0}5zMnhH=-ECeM6i|-%`c>=6$ejhvs*Z7fsOOWOF05du87hDPUU;h%a z{NG2~{}aD>q&fc|QMLcZwy%LOaKZ>gtd1E-usZJIc*-ON)6aW*V?Jq?&XBuxX9DVFq_z@QH6IYk4}aq zl(&iUKBhc689t@FF_cFQ%hSoQkMc~=RQQ(i=wvuac{G#>KT#f?3^kPZ511l*vHXo@+z$bcNAIuFY1^)I1vS z15cpRVB>d$1OK0K&3LNKE)+-j$7zVpY2@zNhHRrq{iW@F{!U!D>k9GRl>$ZhyJ(lu zfPur%5sA*GfY_jqsK^uG2(SiGU*-Jg;v5hca6h7U{_Su%U|?V|qF_#V2~nGO!L$Vl zO}BfGp{Rg(feI4+1o|!t*BdM}2&N;=I>m!DxX{r7v7rN4`OblV1nnmj{+Z_lbzBnJ zh|G83gFAQNJGK{s?hgtN!q0`A!NLhaPu`bsH)R7XPf$^OdoJ)HF##WMF#M6DNRU`0 zhH-&`{Q~h_2hQ&v$n^<)BCvNLG5Fu*Lq3i>sxbr^f5N~Vpk47JM!M35=MzGB$h3V3 zg?2+uUL*M!opEB2n4{U=8ZPL+?PL%l%z~aX)UaDHH%7LT4~^ z2;o^tsE!KisHw?n$H4Z8kD5>3XTVP?oxGK6B6oLIOMqom!aX9C>lYXZ?NxIrv$Ix< z#&fT4v3YzTmCM1|zN#90dDN-O>%Tjl4_^PLJBEV{y(UJG;&f+ zH_`~c=eQ9Fi3l`r$wHWkP>8S&foU4ZZoNN%srSJ#C8LuzE0QRTx-LU?+>En{%Qw*`DR>#-=sh*ymm>Be-svS*~v5#^V>p z)QoPf^sH`9M^d*G`nXG1e9`5PzR4u#c>2tbss9L5Ps=0SIrWn6v$ zh2KAs@|K!4L6vnTWoFrJsi-hD!!{-{JvD72moYZkp&KyVGqsIKh#%5_uv!_kCQ&XUF&!V$q3V(|$B$04bIwG~9F*m) zj(xF*96z8(4{d^K>YAQ7I<>F*IVKRP&cv?HEPGPlp51%&?$NVHFJf>cjqS^3t?7wl zl9SZwDbDKL)YLV_)OBc2Q&*=exo=9wcof}r4C2RocTLT}N1yB<)9sEFdsjTP&^0L& zj~FCoxSYs!WRA~B#-j(Q0gn=N9g~rXG7^*i-c|c*P^Lr8Ov+48$Ab3`B|Dd6+TQ(bR}v4@_Mlml9JOnTWn@#8mF}c;Y~-GJu{<$NF*e=#yaeY$u_4w zZ47j9P0X@4*U(QT#1HR3GOjVKCiHxiS?9&3+7nPc&{cKF6khoDIFU8=ezM8=q`fOXmopPRm#* zj0Se0L%T8>C>n-|goc!_*M@AJprZ%F%&+2Rg9gVlnMQs5I?PsQVKt?ayd^|3F~74*2Gswx1xd z-3OZ4>hf(EKkW&q^0d35uDMkjb0ZuyC8R^pzD`Hq(^KiYSj-L4Y4x{Z+HX;>V{(Xt z_FL!>*p3M%YF@en%h&fB1okyKWYNPFI0W`3Fm+!=rD^q#=Tf}a)!mm-Uiuz(eXN(J z-Is<#;Ao1~a0qNS$d}fih*9$dwoBxDojnQT%@DW;y=h7a9D6#$n}2_ex>g1&_E9s{lGOSF0fawATJL|s*bSwvCB1(V{W)m8zF^cx%k|9w!3D%r-@g!_Z;$rV=pPVA`}5o| z%|6-+co}q=Mx&E)heCOdo@F6_&l3^N^M8_uH7YpihMG+}||* zKqwO9!ygKo%BLe3tPS2AO{WR!~=+xyXg6JgBSw8+r z2R+KCyw^a}zBnBn3>d$CCI&t;GWxKlC6f!A@W0(cPRqnBG$jl7=NsLPlN>ImYy6lo zxG^W&@kB3sA)m<`~(hjtE@D;%btu~?;CR1#-KV| zqQj9m(S}u`V8BE%e|J)*!|t?SpPT4Rw`H-yory2nZ4D%=_8EM} zG}D2noLK?%65HRvCK)n^N8{q7EG1|EV}z+z_kH#$lZ}bU>W->EUs< z!3jhD(my`VHnM;0;5b~dJ~yQQQwam$1a1^d-h!U>EoeBr(w%*k)|VF$#M({US%A0jHCxO$_4ZF0VRt0}V^B5O znQ0rFn30S{v)XEnN@={f0d5)CP#Ae0#cHtA9;hGsmj?ggF>dBRRcYTZ-ZrX0??~Q{ z+j@<}v*;+m=PSI85YUKIY{_s3>N7sfMw9oqb3fpWWpBkVw zI%jcCOm`)YM(lE^@mM{D`M(_-G8VRk=^vZWmDY_GtRgI96P;r@OY+1F2&=Knp z?r`GI78(&YT*Fcz(UO&hwTsI>0cS@hgO-8SAAuOP0glFi3C~-*m$`!>Y!z z9?L7Ww3JK~?NrlFc#yNO6Ris|B%xO7*p@_>%aJ;IybEKUCD}fDdfYuM^rLk~8UpD+@-*ix#09cL zKgb3O;}CQ{nww;ypzd)xms%cC|IqkIKbqqd{+Z)mB0@W;UOHYwpz`RF`t5b~yXzp? zq4UwtU^*XLLk_`QLcfS>dU77pq$l~BeJdW{gx9YjiM}(-OJZ$z216c=xMrEHVSi1N@#~(FYW02 z^4*(=N7?nx0bc#u@0#%apE3Bm82zFTUt|-$T67p%H|mF;d_?2Z?Hzz0BJ^*e6EE>m zpfxGQI^UoS*g+ZEK}kLMbO$aUi}PR%U=QIsbth`KU(R(-{B& diff --git a/CodeExamples/Loop.riscv.c b/CodeExamples/Loop.riscv.c deleted file mode 100644 index adb1b05..0000000 --- a/CodeExamples/Loop.riscv.c +++ /dev/null @@ -1,790 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifii)(int, int); - -h2_insn_t * genMul(h2_insn_t * ptr) /* C compilette prototype */ -{ - /* Code Generation of 12 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t increment = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t res = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t k = {H2REGISTER, 'i', 1, 32, 28, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x10000FFF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - res = riscv_genMV_2(res, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - res = riscv_genADD_3(res, res, increment); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, res); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000001]; - i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res, resultOK; - pifii fPtr; - - if (argc < 3) - { - printf("Give 2 increment values\n"); - exit(-1); - } - in0 = atoi (argv[1]); - in1 = atoi (argv[2]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr = (pifii) genMul (ptr); // Generate instructions - res = fPtr(in0, in1); // Call generated code - printf("%d * %d = %d\n", in0, in1, res); - if (res == (in0 * in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/LoopNest.aarch64 b/CodeExamples/LoopNest.aarch64 deleted file mode 100755 index 373339af44e0ca6b6d3538b9b84d2e5f299eaad8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52232 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 YS3LhCkeR6bj}NI*^e%< -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); -#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - A64_B_GE_I_I_64_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genLoopNest(h2_insn_t * ptr) /* C compilette prototype */ -{ - /* Code Generation of 64 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 11, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - 0, /* h2_prologue_00000008 */ - #define h2_prologue_00000008 8 - 0, /* h2_begin_00000009 */ - #define h2_begin_00000009 9 - 0, /* h2_end_00000010 */ - #define h2_end_00000010 10 - 0, /* h2_BA_00000011 */ - #define h2_BA_00000011 11 - 0, /* h2_prologue_00000012 */ - #define h2_prologue_00000012 12 - 0, /* h2_begin_00000013 */ - #define h2_begin_00000013 13 - 0, /* h2_end_00000014 */ - #define h2_end_00000014 14 - 0, /* h2_BA_00000015 */ - #define h2_BA_00000015 15 - 0, /* h2_prologue_00000016 */ - #define h2_prologue_00000016 16 - 0, /* h2_begin_00000017 */ - #define h2_begin_00000017 17 - 0, /* h2_end_00000018 */ - #define h2_end_00000018 18 - 0, /* h2_BA_00000019 */ - #define h2_BA_00000019 19 - 0, /* h2_prologue_00000020 */ - #define h2_prologue_00000020 20 - 0, /* h2_begin_00000021 */ - #define h2_begin_00000021 21 - 0, /* h2_end_00000022 */ - #define h2_end_00000022 22 - 0, /* h2_BA_00000023 */ - #define h2_BA_00000023 23 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0F01, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000012); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000013); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(10)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(11)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000008); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000009); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000011); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000010); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000015); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000014); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000020); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000021); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genCMP_2(i, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_prologue_00000016); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_begin_00000017); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(7)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000019); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000018); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_BA_00000023); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genLABEL_1(h2_end_00000022); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genADD_3(h2_outputVarName, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000013] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000009] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000011]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000015]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000021] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000017] + 1; - aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000019]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000023]; - aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resC, resD; - pifi fPtr; - - in0 = atoi(argv[1]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr = (pifi) genLoopNest(ptr); // Generate instructions - resD = fPtr(in0); // Call generated code - resC = in0*(in0*10+1+in0*11+1+in0*1+1)+in0*7*in0+1, - printf("Result C : %d Result D : %d\n", resC, resD); - printf("Generated insn # %d code generation time :%d\n", h2_insnGenerated, h2_codeGenTime); - if (resD == resC) - return 0; - else - return -1; -} diff --git a/CodeExamples/LoopNest.power b/CodeExamples/LoopNest.power deleted file mode 100755 index 559ee8eddb71b73c267b94e7bb428a8a7b41c45e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78376 zcmeHw4}4VBmH&M+lgxyKF#J(Ni!un<#0?=JrGtWm5F`=QRIswU?oL87BvX?~Oa?pH zM1o5{jV;|xcCp1SmbgWWyXY@==@whMrY^R$i~EaP+R|sJ0uQ222|xF9AVZ9x(qU52c&XdVrW1~k7o&|8)%`Rl8|5)=P{7< zNK4qU+rTO)q&CJc$?AE>$oIUXNqPkvNg!ND8LDz59+fNOa%Egj!2uRbL8Tw*M)yY6 z4^Y;ppa*$$dE~D_OUdeAhU%%DyNjMAl;!X&;gEqA3KA_{A4fTobG(;i2IAYfzI1ju z%knFz{IIwwuyy&e#ZC3gmzA`)lq{usrQCo-v;NjQ2qpbIMW&1&GVe6pQ*jeMAGi6U z>XZwJ5Ak&3CcBb;Ik?IHxw!Li6OFo&9QQ?KX4H%(r#e#MD}YzAXfAbo8v0df@OP%c z&r5?ZOoP84cn|L6i|m?8{tapHA4-Ftkp{mk4PN-efsknRx3#sjiPr6*cKWGnti?lH zAQ;*vn*Gh~{*Y+!hgxeJ{Oy7J{Gz$FttI5I3yJ31rlyuU(H^Qtd9m$NZGn(q)P`CD z!skPr)%n^(wQV6^b8R3f=$RsJxmdrks(h_)X~~k0fvlmqCCFqxh$w7H|CuqAui?J{ zplSzS>ir^IZxij5iOZ!M{lhg#Q_QKW(1cfUN_lQ!ldLX7nqo^`1tvTr*^2WMiZW5 zQC+Pjyt&O6h&3aXyB>%>Zhx@T#>g)lBfoWweD@gnTQcM;|AupmI?iR!3&SPeUGOpa3@vHI(`AcZ zd{?LLs|L5c$~<|Z7^!Sww0IlM^X{+@?8q_ePR?SpV+Zx?WC0O-;|PtE0O9+-mRrH?N53kG@@c|I0V%`roXsu6}uE>HXii zA#~NtJ4r`ffBA;*LeH|{q7Kq^rRXa2idWt?c>Ll9O%$zIF!$OWLae@UZS^CaWE*7< z;G$G+Nbg#MGOs=Yzm&m7n((ZUc12r5-LFEfS0U@ergjHi67?BC*%AGfx1WYA;oQ|7 z;SUEoex>Dfl#10Wp1MuI_ns9VvAP$XY9-(_?3LeCKSFg=oEde0vLihILDWB`qel2vJawm#vedIIfV-%kLh-w3|OBhI4E@P-AQ;Z18hA4Ok8H19f#?(m2r*s-WM59Lar5BlNCn*fRS zU484yk$396yWTeXF0xM-WLN!Fk`7ur9qwTrTE)(h@chqpg#X|PsYlqPM+fUM7j-wn zZuI=xt)ioe@%O=Yt>W2;l1sc>=Z(H)$OU>y3!S82x}gK$+tb@^ex3DwNE218xWV>@af-ngs=Mn{OUx%qI;iO zP4VgKSRm%EcxpYRr*ssW{9VkxqI!>_@ADww3LFrsu z0RC!(?}1BbixiKlj7?NUH6e(0S7~Jq$6^)WwTN9MZ&mL#@GZp=@uI#5u$RinzLL{( zMNZ*feODR9tcTjqf5+SPKB;#Zbgz0?*Qx!_?<|`@Jf!a<4PTNTu-&fGTS@k!PNVNx z-AnRPyr$Aw(zDJZl}0=CR*u%4>`5-DyLxF zc%Y1A`kwRJ9b~`ohAP=!$QDWcok-W;DO;4Hzw?R%xP7F1l=_kfhKqK11dUyyX1}y~ zRqs6Z1C1}J`vUIhps1qpBTD*0whLw+PSNM3exOk7jAWV0QeTE~cMbWs4E}xMw}yXp zy~g_vr>S1U*F_H^HUc+h7hw@xRP04L$}8-;I*MnEQ`f*&eHb^pyu@z{`2CD|ybXR& zn)s3JCpspmw&8(|a7R|XX~;@8m`LoI$4WKM^n>S7*nL1eJ90vt85tD%$Z0Y6!dcic zB77IV1-r7X%6vX`>?=;lcq@uJM2_s^PV6cNoPv1!&oJ73 zZ$IidD)h*Jm>WF-eFw!E?`z9xo)aB`P8Zyw>Oukcty{80WwPF+tJ0fn@P6uDF-dyY zI7aL3G3gE4zOQ=ko+Q1o_c+SmWhT9C@3Y>=vnMCcTWzED?lS4Ez2ACIlE1^6F}LkP zzyIC;mwKK+<3d03ALV@2$5B7}F4laJcW+*SeHYA;%U2B}P5s3Y=QW+*Lm%@T`j~$~ ze-qxc4tQ=@FYY zH=2+Bl;pCR-$XAJD-lZSw3Y??+0P`6CJNE${W9yk|jDJc@PT%Lrj_a-bOJn>c^KakS zdjCHB>ov_~l%6!EUot(rJ{Wpdo8~T)qUY`phMuYBD&{%b``uoHlhj^Q%~d`~dY4R+ z-fFJm)-iwhkIZwGH-Ba1t1&6voM1e2l>qZnV_G_1ll+HF^6zK)DVBQ1kU#z2!lj=}oyWR@+7|7XC_j|_5As7XuZzmi*F5oy z%ze#+oUdXkU7H?HU-Ql@MqLz>nfizE^fga2uMcYfu!i^JyReVfjeWcx?BngjK3*U8 z@jl1;dl1uKPTG_EOvLCD_F+$M569R((0vhQsIBioTlq_*sZDnQPrN7{Li#I6U++%b zL+dJ|_C3Bf(1r5dSc~>xExHeK^<~&QJ1f`3TUWLshWuwU$Iv>?S9+(5A<~!D)?b7S ze+d~#pX9amGiQvtNLE^_V$Uz_8kT6(8kW*(4Xg09hNZMx!%|wUVc|FIAx?Zx_~Y#N zLHPYN{C*aGkHGK4@cRh%Z-ut{f=lyV_z>27$s(7S23w)$b>F#`VyZEh5L zM%`Na{nsP8qEhKgypyi1vP0c_v_??Uh{&A@vLc&mPf+FA16_m!Am&^`f; zsZ=l3MRZfZ*Sweh<~f7TrLFFzeo5_-{|aT)`uP_~t37g6C+(3dz5_^;-KdTuQkL|4 zk+m2Hr1!mrattJ+2S9-jn3-LhO$v$GKW}lE2kEk@w5rU6Z7DDfY*d-e=J_QNKod z)4mbuO=Hvv;FaFA|Ec=5ex%iSK;szA!AHIO0RFk!oQQ$o@u`Rp31 zw$fX*XVUwBTYFafWqnwG{PIVc*B{SwzKZd5>kqOUtv{0A$C=;ltzcfN4@}4FBJ)aq zA7_5I_v?Q($j>x$o85Tsikoez*51^P)a+taTC5sC5yg)w)RGXuTjdcq*U}jdqNDRPWvFMo=at^;di%1U zU7Gdwx71me%E?`C4*9LyZ=Kj!>PvEHs?UR{WRvEqtoR9sP7#g)QO#(MiwyfdEu zQzHgWjB#En`jhyY@tA2X_&w;V)`HI=t=59yLYmfmzxVS}+W6OkXv^b1FXhFWC|Pf{ zCL+Dnn&|z~yJC{`F2kBAS#PyAAidRGVmx}MoFnrb>WAQ!ZtYL=t8{Ds(n)$JRhi<< zzz0e1C6lCgwdu?Ntre(!oAp*}!SVQ;d^&1P^gEu1+&xKgp6Wa#%^lTw$oD(Wmrs(v zQ=NzWAnEK(lYZG0kUB}VB{{QjPmpuYKc@q_1m@WZ7zE0OF6&+pL>>a0X5`pnMnX6`fp zg!3;&pZVf|QP-vDGe5(;sQr8p`?=reJ9FdT!cOix^M3R_%5NU@p~>%_AH{e$o_EhX zn9ls}IRbv_-NlgU9nB!{s?Os`za@QLR7`!JdPj2@>6GiwalWG&6vn?_oa}csG(V%c zfcafJ_1%|x@1EXEB=;@j`S)nm6PS+=!Vlwp*RJMgHRx-mekOZ=Uv`PI)9eMyhp&BWL0z@N;((w62>~}!wPUNM(IcIn@C35 z2c-8+Bsb|w?~hfT^!`}!?MIs0AkonKV~UwkdnNmfITyudy0&^F%DtC9=`47<@J_`I zdy%a?8O{?GVoylvISg5qp42BPJ?TBF(v$Xlm7X+@COyfPbp9u$o;)|pr04bEk$V1I z)cMo|){GO;yA3HXYHXco z98;{0YOfr}6yxdIYo<6ZnWQ*w#GFFuO>-z}zqFpBIh4|S5O~#oX%3~@FU_G;KSgt> zlYi5|=)oFJ-%QyvP@{Z*)2O-x=tCuYx~_mw7Jn!rvQmtG+WGuVUu49K4o-7mWwW z@5gsBFS6lSa|xnRa|ueTxrD;gT!PXb{~27wo%jF8+3bXGI^+3l3pi4jA)=hw02M%?CVyG#9WNbiIV9`2&?Z%;k7WTev*(W%(K|54xBgT1|H7;_}^GKE&n2T)u;t6OJ7_av z<`AAK_6`FI%+o=~f8)!Tr}x?BMnMzpw?RhjK*Xgzi@E5T2%T|%=m+|SBGgOrsWUTW zsP8g~^Q<_=bsuMVlHngXQi=K=1g_7y(~CYSfme^9e?PJs|9)gNuX#}_1HIvwekb;Gox1n6 z8wLJW&D;xv_`5dLub@wn>zE>0C;AZ9?JUCx!(rAH`BK**))jP8*K>f>RzcreO*S^! zlJPk75{E~JpMhbYa#3E2Bi3( zWjEr#0M8Wva{$Q?pzj^VI?HTJvmX{9pZwsqABYs#pN)9zXCj4m!w--BP~R{ca!{XL z%=Io~xRPN7%2S_@d?`mM%K+Mk8+`-qH91Ze zrqL%=oa}fyv7L-SSHHx0R@AdjO$A=7_A*L57DJ z9$_7jFLmr=9YH5`JjA+zE+KCALs!s54@2MNxcM>mky6Q=DsI*!$?Ss6i-040W*S?P z>wF&nR&~5}zVMXM_Kva*1{j`TILJ0ZzO>0Pwh8E@O^yRnT!OyWondS_iF}I7qln7^ z#N`RZ)CZGSS}o`y~BNjQvg(d97o8D@RnV0}hdpNoK`uLE?X&oJ~Efj%f7 zbve@a(G%&@K92V)sq{$|n~xn%Y)=J<&0dManu2wj#c&S81*{|TrO(_BV>|?%^jQHQ z#SZ9uT^VA>gM5meJja2^EXT8vIgT@t1&(;1ru|6Ykd-8#8}hyWcSdX%vOJ{>y$s91 zmu!rDDPJ+m2RbR=GR|KKNIocZ%#D^hd{LB-mSyn4MEbNBj;HoPs+gK5^@-1eJsY}$ZDhEa;a#i)@}-WItRv{8j@7Ii=o0$03g`-&=w|4f+`nl5m|Eskant;_iE&d1 zng0;DiS}u)zcl_jFFX-%do_;uJgt>&5@ws!uubaOCXH;9CP0cy(D#;Rh|3W2DK2Xe zmyL+aR>Wo4Va(Is!Mo;rAP3FUI=J554EHeHi}DnI$d|t9VmUx3ebdePJ%D7d4)|m@ z{DJb(y_YEdZb>sfrHa2t4;lLGWBL0S9%9(f@*-dAv!C?=oz&+b=N|?nefB}0KInt; z(f$njOr%evvkBwv(_Z{qVr+U5o8OT*>;th*#~2=Gc#?HMzSQw3>j*lj;{YJV4(NLe zGsMmb>NkzoHX@mi~dF5up~*oQpk5DaB7}5Xo~H#EMEkCDW(PiX`Xh9 z6=7A?D(5q|!U;(QEahH2R>-sI_|M zV~H`f1wIQ%9QNR{jIrO%uz;b5bws|@F)zy)CqXB5oCQcR1^V8~3^6qa`4m&GtOF5u z*0Yg;^ z@|H?Dc6vdVFs3ZXni~a8bXnGD8$bEY)G?FF#)tm&67`HA7N0$_j4Y> zS}0Xtk*dzez8Y_LWm)ktrJ8NBg>6#CHmP8nRI*Jr0+J6w-`kVHhnta4J}iR|E8)Xx z_;3sR@QH8f8?J;L=5H{_2Lmde~nVu(#UGa_r@L z_cJ`m@G#1gZ;&tL*vE2!PRh{-=tTY@K(g0f_+&r)f%4JA8Tz-0^w(90t5oeERe$|R zU%Vako7%wu>vIBfl0N-_H2xf6eU9Rp#-C%He;knX>4!c?p%2POPh`+%B6ENp&!pBT zRh+zVATc(>)c;AGXT?d@=@i2uhUZuZID6$P7AYaONp5+6bl|h+sKjCYo6Y;k3}-Q%!#W~g>gdWg#>_lCQ=GX0 z$p@hC?attX0_2kq9N7mVdD+iKW@Vp=%*l@X;IZTSh9@3Ll&=T!Jp`PZhk3H&<3TCQ z=LKJ~u?LXa!2*`A5YHrEG3PG>JS=c_DSK|TFxwYJ`KUL84>Gmu!|0=rV0=4i5WvOA<$gmYW z$^OWfvfah9flkU+4@k0sKI2||6Y@#6Es(7SvNb}s)@)-=Mf>n08unyj?^Edg8un;e zh7N|i8SViuk_q`zrZCF{Iw?~ZAjt&!jC;J@$S0XXkf{SQ?S@QyO!j&mYamw&U#fWR zF~w^i%XSDnNwyw9ir2j?+de!~yzU1i*+8FhpYI^@NwyxywhyxPLAFC|uPFAw3liF* zVXwn1!x4tZ7#;^Nk_q`zrhb+QbW*0HfFu*>GwvS^AfIG944IBVrel!lxXE7M#ag{E zg}um^Cs>w2hNl^x1y7O<`BJu%EF0*gY^MN8Hqd9>Ll{Cn$#w#=4MMilknJqn>ly6H zdsEo!9LsQ?;TsGuf)~kzd?{0eWdfa)X&8`X0)57{=?L;krgM<#JY;$UGF>#;tM^%b z!d_hGZk)ZQZ`yV7`|57&XV7=GaNbtdk@e@snGm9_!TBNKsPV4Y zhuFlqZQPL^KPNo`9j$ohy%qZ)fH*(47Viy<6TZtwG+~qnk6lwl(UtU#8~QdC{S8LK zc0;% z-Y;cb2N{iT+zsHI-y?hCXJ7ccOuNW;hA+q#3-Rr|3i(aEv!HKg`Y_}JU-|8*Je>Wb zw&23w_oUb%AN7s#_g<(D^LPJF>$Pv6)pxxe{)2CK&^Ho|?ey5>XCPM(l-;IhF^Dm-iWvDSLr)T@jWN<@d&=9m?ORt4gZ^eXZYWD z?+m~C)t%<=CF;8VG5R)PHGfAE^}mYxUsc~oq`x6!`bHwe6aJD6+e-v<~n>o=4^Cn`()&GKH*58%9Daq)S` z3>x{})KbW9`dc?O1AnHWs1U?2OB^VF+}4O#q;FB?MyhK*-#P1#YC2Epc{r=|`RD_~ zB24^U;_j#i-_$&*>l;qsK8||;_c7c@aUa3mkNYt0L%0v(?!&zwx7mN>i$|f?n}`pH zP=j*r3+s*lrA#q- z#wU)5(ckikamgQ}FJHfIJOyI(Ybq)xL|?vUJmhitH*K64{n}fq$5S9C|E4?2Cq#ee zc&PFHc7OZ!rjTbXVt8Ra!dO04$S3K~^+w3~>xo^^GoPrEV$l-{H2Xc*FRZ5m+K25o zoCc)tf;W9m*Ij7trvVEA_kUj3Hv)#gpzE!G6@RYlJ%D=w`vJTELe~cYi+gl^7;q1u z8_lgBqkSo$<1cl+nwlTJf*1lkjE|-613dYdt{($D{xw}c3pj)h!C@C-Ut%h`#D{20v!1s>ILloXI(!6c=1QNej2dwg05c#9DEBSghPlP^yr%b3ok+*RO`k~ zmv-On!VzAheK=1O_|7Q40WCx+Xd5ZBJZFt4&t5Z!aJcV!5Oqp?e)R!u&D6P@PzaX? zcQx)q$UhD!Zp!b{rmwkQ($vLiLddFw{f4O2P5C`B8e2dTQ9b)`i#@u2l3+!CndD() z3(7x=`!MpUKIE6m{F{wBD4+Z_g#0%s|EByhB}NNKD1QWZKYVtO@+(*mU%Y$)WLpLw z)=+*q*Iyma$DvaZLjD3nhib+D)69Ph@L~9VGnF^hzaIG>pu)&MjQorA;c~ML>`!Y{ z3(@Qc-2FveKa2rBk>*O9q8R{9-T}k62{g91h(z)^hlJ~^x;{dPoAL+Z_HK>QxG2Uj z$P`SKH2pCeyVp)cWV2$>3_i^^Q9ij0@Yr@f%r z|Bt#JL7XPi6vu3H6f`yer0Yiw8k4-97|jr9-uOP+r(wUi-uA3mT>@=m&LBqkg|e=} zY08oIRXL=Y2WV<<3*JPm;2HAt#cX5yW2ro~32KXnev7t;v{;As^4D4W9cv%4f5o=; zfVMuL;-flWtj}I^=H-`${>^B29VoNxztJC18SAnvU|GPjfMo&80+t0V3s@GgEMQr{ zvVdg)%L0}KEDKl`uqU|GPj zfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg) z%L0}KEDKl`uqaTz82R+cY`XAWbV)Bi>W=3xNURXK3=0@u#!vx# zc9}1mERWAb%ZtA0P1h^~2q(iU7*=K(_2IFVP#al(@RQF>7Asf4^z`{@x=IZoau_Q4 z-qj6#M_51DQ|hnmILyyK;e0MWd0?kumvj{jvfkl_*IdZNND8iXojitSIY9M(F~1z)s9IHx>P$> z?Z&{ye+_wSW984@XUIDkCrL;d^}U5=Zqzr#{f3*Vj&b~{=Y+y|xE43tM>e4@w$E{f zL{Fc4-;7)9dI5SnWSe(s?V!(FhW1R^TXEYo*UeyMvpF9l;Bc0M!sc?WBA{i{7w_$V zjI?&m6;~3uE$b-&`&aR!70y{e>32b+70tREX@?^#5DW?X{gi#}<$nNRb7d_?`79S| z+C<#wgY>o!&Gb>xKS7SYU}hPmAETeyvo;avqMr}VY9la=AIH2IUkAv}bNt+qqa)?4 z1uMspBmW=qAe^6~r{<TmDv|W-ev*(!2}!C?bJ4H+IYMqF zo>zwVzB@+!!Y{|kwvU-x-Jeu*gmTO#S#twGu85v20-kecSAU-#uQNuG4ilgURY zSuB%Zr{u?E^81u5m&qYY-XfD^WcL=CByHVwGI@xSL7DsxC3nc=zfy9yO#TNY|3W4& zQu50(IUT?5$M9qSA&}0iWW?ufLv0S{To<`*Y8Pe9o7Rss$Xo!6vcl&$Fh( z(6d$(a%hT7--fczmvZM3zL4-Q=Pp57;@%8}1bkwXq7x5;O_$lFU& zI#0VOLZ(h3u4i)oT?&yyokEi$b)w6#9S8Ac9#?t(L85*e`L2q5YO`W$5Jg?wpzk;kJppW%*Czmo75AWP!BS^$@TQLCx5u*-?95 zgtL=-_TPYndpP?LXlyTDu?`#@%kaa!XqHj6>SBz(CA$d(bUTI1)dnd0i76YAnnHb( z{6QAY_*|~P!Y_B9xj!KF7EP-KD)%=KOCHfJR zq)Xes2g2u{lDU^t%}B{B|22u5PlBw)y$W|e`CF?fCEP=}{{r{4pAp@i?lPo*iTf4Y z?ot+jEI`-&sAPITXj`TcW*(mA;+}CAlg-pN*}foVYMX6)@Oy{t^B|g~c#weNvIuIS zTk}q3*L@8k=F+H9mw~{MWpe*p?KR}vMFhX8YG`d~ z4}=$Q4TRbS>Qm6)w2dBB_1lA>!Na|an*zb@aq>XWA6kr?pqXBY8*B}sw+roP^|zNa zlBDgSddw6T;SK_UmduFlaSW+9Q?5KsOP(&!QbR2VJ1c57f!uqEU# zsUsVNny3<5M9;@<7c@qV(imj}A%k9oBpHnuqsUCUD_t0p>Fe4;fw<+>vcdjO=#}Tq zBimm+&!)lhaEn?)*nc834Kxg47tN{aUEIB;_k`xMRQfN5wDw2Sv<`(WJmY6)d8(qMLFbhVJOFOFd|IdrjVN(t5vHMcHq zZ>w9}00-19T3T}5b>?JU`*wj9tY^(853-h*EQy7yFVNm%dI;9GwF;k)0{ptAzL01S z1eg1^HMM*y5Zq>>+a6@1CCiDZv865KK@k(9*052wy{@Iz?+es}KGfLeudVmB`5OZ5 zA%7d?`?l3K2by+>bxqrrFZ12m(pE2mjrB5Xxvv#mQH&(mE}B|`4W9az?OU7t@mhlI z23}@T{W2kcwg=k-4MBgs6blM1_fg|qvYh4i8oEiO2-Y_HrFqsaS;A|4&!T2D*Hr<( z-%sp}ih&HaP#iC+4TahQTepY&KvDi8gJ98;rC!gX2G63~mU*0Mc_{-yy{hZ>0rV3EJAE!ctwR1CtpyBD># zp$n-CwX^|=K4ejIOTE8o6*ZzjZPOxu*k32wYuT<)GG>Rm##+PV_xameM9@b{x8E1H zCCm(Ly}!MVu!dm_?;9?XX|f@)udfZ&vfE=7B>2C+N%+cJTAI*-NmgWT?jU{smLO`P zZZ?h!Fa4;DhnUZe@Iz_BP-&%8yi6@c2Rrt|7e%?z`!uDR}-1M0Dc(VA%CR1DZ-WfhT4l#Z%{$&=q7sENW!-uF{;gClA7 zos-L}!R|blSHs-NH05Jbr%2c_CGe`1wJ9Itwur5`6Y%!fdkhmAW4I&sJ|hvI6?>17 zh|i9_??}WuMXL7zcI=g^_XmmeIYPaMNW@POruP}KEIZzwbg|uHNF=b$L921KZjNQy z#njmTZwx8v^F^xn1a>h^xVuvEaf|aQ@zaIp9W6z@Gel`h{7g}n5%`HQU0{)w;~1TOwfb^spv09ek%OJH26~Bu?QUH-y0=z}@gQk6apv0|= zFU?7et6IkQCE-5>ye8s)B>n07Gu(vlVgDL$AB3QNH>$UFN+SPsdVN{)nJx;G;_zz{ z?-t?RiG04n{0Df`2aodlXZ)tJ=MeBD=YEzGD?NGrn(=)}@?QkrhW6XR^3$4vE(a7R zy}G9w@|-l#Vm9M9=Nou64A6@Ts`o?^{}qfMOu|+>0#HTN* zKU~T9nj}2Ej3Ih&()bf%{6G@@mnD95yZAe%FH55T7sl5l$@v?`dy?o2uxUW@oK3>7 z0$vlN`_G%0zAK47An~K+?2!1;{XFgIYxJfq>HYFUl795K^AEt!AUh{*+J2AlHF;tm zsvu1c(hsf|CEiGze_u(1|1}zpCq+L`d&R_m<3|ntBQg#kJLspI8FP9j@NV!)9v40Y zJn^acn89a=4=M~0|E;6P%|b~(x&m(+{LRci!tMGv7v048p@oU^Z)N=9T$YFRYL)oW z^?o4@{s8lFtvC1_#WP(`0ZzBg5ZI~c1@oz9J_orUeuMFU z1U%`xkNL10MUd&;vyFNWvpqk}_){M-@C8#1MxO(o7HCxi>iSx@0d1_RKY2VbenonGdW4YZP+P-ZYmgPR*+ReA!?%P+F`=_Pg5&+2(KekH*%vH~U&8 z^Y+?%{l55PgFl1~45MgZThsRTMq<*8ji{D7^Ik-$yq2seX>AJm>X2R1+J^0&ZDnQa zH&&Ie^(`$~@-Z=*2<%&H8~n7!AA`~#4ur-aY37ZtG01o?L2j);lR$6``euJKOqM|8 zgYyHyyM5IgH^ZJSP51g!=+?SDL_26n1(UWcMwwm@hsgBd;=gHtOu z3tN&ztoXxQ*W6OIHibsDp_V`b!-O3eW3S5R!>+M!U8T>6?aGSVMakyd)|N24rCZ|> z0xLGR1dTl|*&JefJaRh=akj0^??(g+>3mZlvDjt|y+86b_=DwZeAucEq1m>XL(k`z z8<4UU5!t4VzUze4$Hat9X2QrIzTJPXh!refzYY~JzF`ykl-TZ+DWXg)IDAZ)7_Uut zltT*cZ;W05qNyeyuk%h&nOlm97kVOWtnxmgY~Br<{Glq^BSThui?6XZSdR_xqBF%fV1girP*sGb~w8o0Be-Y3u!ylq2V%-bPmtl*l83aQ)H_I8$znwsFy zHB}uev5CsZRETq0drLKB@cB01vX;9_?pn-DxUHE`vEIOhi`8}ey3M{)AxheJG>2-p z0*2ZQ*r-zIyzoL&l*rd_Ys#w@(S~pdcI8VNYtado)b9wQumMADM$WzdwszPg;lYPI zZ2#6$0ZyTd6eZHkB_V$pX&LS%Z7niHOZ<(9dm1umuQ~Q4O5~t`3TbSR^F<2!1=dsZ@@lsZ4e!-dXz6^RMyt5Z3u0Cq8AM+4I`)|_47=@oYWxu z-XZOj(9}dOa{$#o9iY6D=jv*nWaJvJKb?3`<<)*3pu9W=i2d?3CHDMLq%ft3l~?DN z0p(R~07*khwV$B)ECKGfINPi0AK-mPKzXShAF6{cRo-|K@?|*AL&WMo%jE&(MeAm| zXgWqoRbK5>tpyHK?0hx4GS;?>VB?0B7cA%8}icY~TprW(S z>RIhy(tMsSkNh1iKchth5=5%Xt9?#Dd7)*>OVyvO|2@d1^5q6uY(EtHqVn>x!t_YH zgvsSU4IGj1bT_tdiv3f0seKmXDXx!t-i3s@yin_F3QAmk+YP9GJu1QQvw-IEYM&fX zUd2qO0Gm}k%JcG6UfECW*8n>*V=jN5 z%LB@*C#nAA@=tPkMW*(NJ?|Lh)jH64iu+GJ(|V2SSLM}ya_KnBe;Z}V)vCPOcP``d z1H>GciVtN!CD(D}nd^`3PxDT!ieJfuewd%)b1zVoR`tV^l65JU4^tV_rOGMz1LT?O zSL^C9SES@rEL1u5{C|-!*RR%X-CVv}5i(3Je+qc2KUq&zenwJxR-d^G@e-F$A`^W~ z;ZX&cAX%UDY03}ClSOo_H<5D^J28@`{E*9_d`2}aW|Le#8;E2akv^1bU>o9&l^l|3 z=@d5MlI?df-=Hj19iJ>6uS@Z{lFM^;3@n&sP^?pgN#zw`VVd%-ml*}S6d}W8`x8}? zi6rGPmoLB;E?x6*e;l`pA2oi_zoSVq5ip>;+Ni%!H9U!p>(7tan@C;0loZ27M`+Dg H(xdqQm5t+d diff --git a/CodeExamples/LoopNest.power.c b/CodeExamples/LoopNest.power.c deleted file mode 100644 index 73da90f..0000000 --- a/CodeExamples/LoopNest.power.c +++ /dev/null @@ -1,1257 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); -#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); -#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genBGE_1(h2_sValue_t P0); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genBA_1(h2_sValue_t P0); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genBGE_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BGE_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genBA_1(h2_sValue_t P0) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) - { - P1_BL_I_I_32_1(P0.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for CMP instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for CMP - -// No specific optimisation for CMP/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, CMP instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genLoopNest(h2_insn_t * ptr) /* C compilette prototype */ -{ - /* Code Generation of 64 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 15, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 16, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - 0, /* h2_prologue_00000008 */ - #define h2_prologue_00000008 8 - 0, /* h2_begin_00000009 */ - #define h2_begin_00000009 9 - 0, /* h2_end_00000010 */ - #define h2_end_00000010 10 - 0, /* h2_BA_00000011 */ - #define h2_BA_00000011 11 - 0, /* h2_prologue_00000012 */ - #define h2_prologue_00000012 12 - 0, /* h2_begin_00000013 */ - #define h2_begin_00000013 13 - 0, /* h2_end_00000014 */ - #define h2_end_00000014 14 - 0, /* h2_BA_00000015 */ - #define h2_BA_00000015 15 - 0, /* h2_prologue_00000016 */ - #define h2_prologue_00000016 16 - 0, /* h2_begin_00000017 */ - #define h2_begin_00000017 17 - 0, /* h2_end_00000018 */ - #define h2_end_00000018 18 - 0, /* h2_BA_00000019 */ - #define h2_BA_00000019 19 - 0, /* h2_prologue_00000020 */ - #define h2_prologue_00000020 20 - 0, /* h2_begin_00000021 */ - #define h2_begin_00000021 21 - 0, /* h2_end_00000022 */ - #define h2_end_00000022 22 - 0, /* h2_BA_00000023 */ - #define h2_BA_00000023 23 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x1F80F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000012); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000013); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(10)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(11)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000008); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000009); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000011); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000010); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000015); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000014); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000020); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000021); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genCMP_2(i, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_prologue_00000016); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_begin_00000017); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genCMP_2(j, len); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(7)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000019); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000018); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_BA_00000023); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genLABEL_1(h2_end_00000022); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genADD_3(h2_outputVarName, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000013] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000009] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000011]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000015]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000021] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_begin_00000017] + 1; - power_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000019]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); - h2_asm_pc = labelAddresses [h2_BA_00000023]; - power_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resC, resD; - pifi fPtr; - - in0 = atoi(argv[1]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr = (pifi) genLoopNest(ptr); // Generate instructions - resD = fPtr(in0); // Call generated code - resC = in0*(in0*10+1+in0*11+1+in0*1+1)+in0*7*in0+1, - printf("Result C : %d Result D : %d\n", resC, resD); - printf("Generated insn # %d code generation time :%d\n", h2_insnGenerated, h2_codeGenTime); - if (resD == resC) - return 0; - else - return -1; -} diff --git a/CodeExamples/LoopNest.riscv b/CodeExamples/LoopNest.riscv deleted file mode 100755 index a782ca2fd27bb2e325c12f423dd4b1d88d45da55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49712 zcmeI5dtemR^~Yy3n{0RpXteld&0|^95MGw5RSaPvpa>N3S#1bOfY^}4Bv7regjyTv&@SV=@i|S4qQ7JOJ!MdqRPF?Bc} zN8cKUDpO&rrpUacKSECQ_n}|P0ca`GZ_jZh{41H86gTZs?7oQ~7iSeLVUkN6s(eJB z6ubZX^h18-5d93VO`<=1en)7NBJvEY4b07%HZV79KyFUn?70I9bBZ$O3>`8cC%0he zkgVjQ{N%wFujmr~wDC9aYuZ6{$RQZ_qI9RYC}&XQ=t&Wr1cPpr9uzr5kIYZxY#mg! zXsb>7rCoGs&eXvXDGQz{kxtF∓)cy88TN)jfkY&Oc+@#})lA`pyGI&waLJ$Hs5} z=$zsAEx+fgr>;2T-21whw|*KpyYQ-I_au+M`rx`H-}?h%?GBmiApA>?vnbb7riRf! zfG!B5g|j4#z8G2yqo+W+!|3y%Q^M$PLr)B&F)fa5j^9W7d#lW$GOXVNeZU!--w^0N zVf{YnC1JESBfGdDV@7sS&fVEs!R+E9tsuLwFuzdCo|{uF4Vg1D3bl;l{2XmoMs99? zrk0+L3uLAj6=xI{r_ajB$B&mx7atxBXI2^}iQa9n$ zE|dMD7Ek)`w84jP+#ZfuNNZoSSaZ+q;;=&95)`6be`l=?4zy7cXYl%w-DKU`Y+ z$jj|{Mw}TN^f%5ci`urJ>Go?%)8YbuFMB#A);Gd2zhvvPcikELmUeDja`llokMr2z zN`L?0u~Ju@$2dmqXlZ#|vT;OeAGb))@X{euMrF(|ahw^oD|V;WC(cuSEG~XMyn$nn zyeb?qZ}&|R>S*81rB{}|e~q-2J}|FwscV14d6i3DQ=OYjKb{d&>iSdZ)ei0Rlxe<5 z^xbu5)LXH8ta&7@KN6Q1JaRNGE>>pYI~wOUj_ID@QGY_71)+KPI!hs8(l$ zU!|>^(GoGQ*{Y|tM3|$by?5z%F0B-q^7kCyk+~f0Ypw0rhkIN{E*MCO+7`4fD{^aSUzkFUOTRK`$;_VmP9g-aNk)+*w>dyXtE zcT_O5qbpxBYk{MCt(x!X%0{!zd30~1Lo?CEV%xN6+RI~*>^XAc$g|UKPJ8gB-7hU` zR9wn-whe@D)ks-YT)gwxcWPyor4N*TDD5jp%B)LAuUm0YyM3{0c}ZHXHtk$)VgZLs zR;bHb(>^@VbVLwqeDClTaq}HzM{gQl8nTn^E$FHc?ZKn#ZfZ#>eZWTbk!E{byhn|@ zw6Uf2UTbW7g(gl#aecP`!`o*|k+;wGI8PSyKf5(9*4gU!g044s?87C|t#VE+oi}P} z-$>1o=1&M5OD>x?dR=y-76-y_E*Ae}-bZC7SC($J{PTE!vN_hdT2f-(?ytqwzF#r# zia1ZTc=@rRt^@dN@aW;i779w6@Ln`}bE(dl=Uh=&{z#+pqx}h2+_pcZ{>xNmwLf&CpOvcp{g2(O}URNH%_J%vl8mnHe zd1=Si@%u`;5s?Rz7d*XSLtte}X=1)9I+6-{3~*75F`ixxA_mbgln7FR{7rqobsDRq>3mnQv@qbl$U_~t*W=p~Ip z?NPr+Z(JsE-Lm)9QPpZD{aU)Wjd@;6ce2KzI4>oUl0-?SxSd~M$1nWMEiT$Pw8|Hk zXdHUi7nful`qj`n$tj1h>mefOFp+dv_XH06J;B3ze`NamzChnU;}WY4ENsLj2aP!Q zo`Z3*A05Ox2lZN~wms!R-)`TsF?+|X8VBz`;Qbul&*A+XUIShOUL(fk{Krz4^Pg9i zZ7%hcHurHy`ulg&e)dca`n=-%EqRqyxao)q4A8ct~ZMWYrnD*Mknx1AM9mA^o zzarT;BJ=l6(R%*{VvBQIqDAA@CXs*T!&NEIH?JBKvm(v$tm}Z|-o?+lw3OQy)8|;a zyhVGqytnqx#n6ntbor09(iuz3U5Ea;_>YTY{`_6tzuK{IX<3>USNZzFA>}KTJ^bEo zn(oD>3D`6Nn|iuA{GPE6Mt8(j_H|%WM@8e##wD-rd3EJ$jwa$#B8Cw|t2XR{(dD-oT;DjLe>jmplBi7fr3`M~`@l@)zO3co{Y zHBzgQsxhTX+obv}T$S=w86PrxeXD$X#>f~8+PJSNS3Y+t-%K;Hh{50E<~N!CnzmB; zW(?NYt7`Y&wDMIVs%3LZvhOipud!d;lEYQy_B+eARRwEa+_7c+dnM6C)E5nbrxy%c zuqtKVUssO71I}sDW?fZRzG}Oyww?Viv+Qq2*V!#S_xhCeUu){V(ueIYXz9Kx<>kMM z=8o1NjHS zePnU-sqGf>jWue`U$t|`zA@o{JMV`fA8GywANleW`RmI_(?`Ax^ATwi&!ElnkuNPD z`Eo;w$G6-UHTLscGVqaG?ksz&YER7@J9h8dRU-SKLk)o;3pOm!u`3omo4jk!$aUO1FN7s`K#%NzJUu4&}tw*$)s}!xQKxuu@(puXM&tip7vce}> zVGUV`*wI3IG2HlB^MQfu!(({Dx~~(%`D+B#uf*^PuL`03 z-n*W4epTv(SA|dvuaO<;sUyLR;lp7ueAtR%+N>BpY{l^54HG?6mQRVg<>1)tljM1c z;r5<5@b@S7#5J!T=ZP1!S$w-?ak9Xwlvh3!%${ksJn{UHC!W~qlFvKolby=mqpI3` z@`AP*ZnI{1mdx;Z<VR(eW2vjd+z$?Q(#mz|oO>6hhyZ$7YQVYpwuCRR9p_rX;) zd`}R%wltTXj$baGe;R(d|C(00KAa*$f1_*5op(mP9s8!|57)jv{x$79xwf#Q4{&X< zcNG`4bXR+7*+<8-XZBFMltfArC7I%O9`VaQI?DKheYDs3f_-$N@dfc;iQgs}U+CVz z7wmn$@FzIG)IGj0{hq*=IxF+{cOF4o3%lck?2ZqzJ3h$n_z=6}L+p+ZonR+@(p@(@ z>3_15ZZUV#m&A#cj?3pO%qVIfbIlJ+%(bnzPfPc`z9-T$cUoTCwtrrg^7@BXTycM+ zu50X}RyZVnLi;5~ZI|(d?<+Y!;&gNVMb&NdJWJ-eH7#?OHP7?Seg5lBt5UW$S@Yy7 z(AjyG%FeD!=lWFW`ox`yb=~Zu*)Hhv+5TPbI!e=w=KZbP!*av^e%m`A?QJyAmYxkCD+}R(I{bRc**#G#) zC%p3P@AuJhSDtUR*>bCOm%+7&*!ZhXys`WFmiXaV$LnqP7jmy~6ZaSU?+@K6m=V** zyw~K;?%5XezVoZsB8jxG?2nFgW`AT_)Ya0wf8VdeE!tXlYTJY?*>82{?H{t}3%|so zM^2Hqk68BvN5b|K(kAx=v|0O!Bi4T6$mbKMO?hKV>MfUGPsf?DyUZt>;pkj4BgXaP zsFg1{xEl{1D^yP{Pi^_umrrc@`-8_>o~&m@@heSHYWK@dcU8(WYR~aoxvq09H=iNg z+u2=3r!2W3lu6icTXWc9&EZ=zhvz@Eysw{mZy@Z^>C`Mte`-98Kb5ufr_!(G zPxDX5pVr7Tz<;4Xo#-jVS9YiS(|>tlPucgxah}peyHmL)eKjL|_e6J0o!b9(?e6p> zv-_sI(<9CMU)vwtQ?94asQaYn?Pm&oLw9nLXTzV#ox~4M zduC6D?%~)|TG{qA=O+8K6GZT7&&}GUwKnfx+z=ikYo7W#G4k54PA5k4YyQ>V9^-J# zi}Rd$UtIjW`(m7q`=M7H{qfemRV(5eR=c_5I>H^-5$?E-aL09ww-@Sdn!FQTDo>t! z8b^4}#=9nY1}yI*f2H0|(#CtU@Ow2Rk8m$1Z&T&&3x1?~8DGHZwxnZ?BS^<9jUGeB zYY-uU9-G~Tv}M(zfgEq8R3c*=3_Vw7}*aY)VbkdpQohaM3* zY2%#?lDt)+cqm>^!KXoyI{pJq8r(_8JF&A#&1|WQe4Jq=BS?B=2h|$rQIG z9c37BdJRKKCmP1ln~)Qk&yo2Y8Q$Aak|}QFVx4e;SG4iDn&0P2F3I>Dxnx6R4j^*? znFGiiK<0B~K4%_qBG=tGpk{VJ$t4>HkaHuK===8RrvZK0)RaWIjRW6J$PN9-k<=2;&pv;teR|JjN%; zd4+O*6ywsOuH+5Q@Y3epkN@-DACKr8yF%~Zcu8F4`wJt};^x0!#LwK+X39H4CR9l*fQl zKJfvwNL18Otoy;yAM;+T-`2iE{pH%mvcV4-_dKM}L;75#&qextq|ZnCd^P*?w)S0DR?fUx$px&W z+^SzB`9hw7oL@?olsMlHR{OzfKUnPttNmcLA3K^zMH%}+%4_UbNF^HkUy-;GnfH)+ z51IFnc@LTQkl7FZ!tXKOQ#eN(??ELB1GzKk!~>u=f3r?hX78e*HiA^}D*q_paX)co)BZ zw`;K8w;sIqg4bT~dI!AT0k3z!>m6)hqSedT3tDaqtytro*Ci_n#&03B7n!}t>_uiT zGJCOs@FyE@DXcXm9c%1WSjQWC!P+BKidwb@c*IVHA7I?h{UT=ZdTj2E;HZakO zFx~>Yc)>8}o%fagn@OlHh-T<#R!0Qe0dIKAnXhj)sfR@*IL!p&uyzxiLC?c~Pncc|jMrJoM zyODVV8wkJ0*lp$O-B5`_fpwCxTjlHBf0sykqic~4yn$E0fmi4=Q-|8(o9+nggJ<3$%8D)-KT61zNj7Yd01!vFdK@ z0;?orm%=L9*!3qtNf6$N%uZx>BC`vbUC8Xh0>YnY?6k7=PN-y|K-z8WQrUXf`w}O+ zx)y2YYr5C>8b19RKK+`GC-^J z#&#=L3l(eZP)NrcJ5;XTLB97=@6zlMcvbfX`HIK66QACxdjdQCp5RV=`uCkdI`|4c zy#t@#flu$yJ;5D*kMmW0`qi#MI{zim+74RVL5r^yDPBqFxOR zcHQHA#qaUGf=|EF8KiyN@ab*%^fr9DQTO;7{hmN0KHbsc;f}j-y ztsoXKv5GQ+VC6M}3admT_!mJ*WL`w(MPyz?=0#*)L?(y@gx_PlXyxe_p%R5sdHO|_ zr(gVyL`kq~kq!j$=^#G+GCuvX?g_l?_XJEMgH*ZC4Y{SrR?lI{t<|IXl((lEui%xXuXI9Osu*aTfi#G*rKpXHn#jtP!fbUBeNNq&B$y) zW(zV~uz>I<8k?;=y%{Q5D3zzTs64&p35k*|U5m7HtM2t}#izI8(_3{s!SC_Ch)=)R z8KiwL=-$8!`1A|-^cLOY+v4{Gw&2rSx&-OnkGF!>bD;GcXl(|q&7idzv^HY_!6?ai zP9fIIcn->KAr@~b7p75|drzINy+`N17GS;|>H9p50 zpJR>BvBu|E<8ye7tSs5sq}Hjab;io7@r-!mxfnfo*j{JwFn-TB4L-hU;M)cd-!^#o zwxPf8%g(Gb_&cPZL;5+SpF{dNq@PFn`O{zL;;qfQUn^7VOq6x@E@O?GSmP$vxQR7x zVvU7Yx|Dk zD@XAa{%XR>Ur+ds;VXRMA3O#MCw=N-kL}z{udhx!-@m&2d_3uJoV%JY$=81o7a#m0 z&a>x>IPXV%9mCfzTU!67tl>63YTk0q->}3+EU^(wY{U{9vBX9!u@M~`!9Uj6sJzZ; z2;~t9Yj}-~F}m|m+nV_%-N!fSfkUkM5Nkfnn)xO@aJVyG=i3P08})?XM)3YEc>fl> ze+%BfJ$zThkf$9RSmOrPxPdipV2vAC;|9D@Ru*q;Q0t5`Hb8lW zVx5V`2D~oG*uYvoYV*2eTEq5lokHPX>~(<+x;MB%PjEgcu zbC0oJSs>b250xks7DzJI^TgkMV#GVl>ZeA$qiez`<2<-t_d1^;S3cuU2t1>Eg3tKz zF1^2RL)Rcap{^5%$2wc$;;RqFdH6=n8{{1Xf9;X<5$_<3gZTd%(0&@Up9bxxLHlXY zUJu&qi3P#fYdozG?`}K|l_V61Co3w}Sl{(N?(8T}oDy;8InPl(l4(wYn#;*6#_fC8PWXv`@KX z3O+@2G!PvPL`Q?}2{!mW&Na+%4bmM%W(PZ_-RZyJdNp4m94`ppKaW+_vnsjksb^L7 zU{%km>sfWZLe|79!VoH6&;w_Wq7sez6Z!XlGNU-_@$Y*4yB`0p*FDas{2t#^`1ey? z;@?}Y`M4AQ-C;(V@QFg-E9fu&3&_`jd>zQwfqWgv*MWQ;{#FOxu|}QpR;MA9M<~$u z8sxRmlT+KZ_6>kZVBEo#XYzam@wifr*Kvc<2+7Ij_ZyVe&69qxKNw8mn& zXRHDJ8qlu+{Tk4(0sUJ1STOe(HOd0fMh#S=P*@Cc~~K z!>-mn!PS1eiws-aHHfEIb;AEU%oh2pLAx5Xt3kUOw5vh82DEF41;N;BR4c^08`V%r zLVXo2g3F=j#UIpq^#6T5RsZzN2GAhB{Z9sv0tWgEGyj81&yAtk7xGUkV z#D>C|Y&@pqG$j{nR4Tc6qf+fZD)GHgj`A8JRmB`cYZY3n(OQkxYP6bm?`c#it>*Y{ zqniE4FYPNr;0fIue1eQpMMkO8J%K8}Cs;*B`6XzddjIh_(NRfsR1zJPx+hra_c)(m zhEE{f!S$r0{l|odo7Z0Rg+e$9gxB8BJvMm7QsOBdikFf|Npe1>kTvm&FocR1^uXDp zs6^wj6Z!XlGNU*j!@nQHzaPWDAJaX~$Ne7PNJG%2nG6HW7Uap?=UlT;4jwxW0md= ztkM&LtNaPhU+5m+FZ`asFZBMwUw~W(d8MQMNAE?QK&zu{u=f7f6k4%@)(i43@KKO@ z6r>&nsYgNTQIL8R9~OM#jYkz)QO2WCUZFrM(RfttKOV&k{w&(8{l}yK0t~;|{^L=y z#iL}4pOYtM zxc_m`UJlyJL3=r9F9&V;Qg0=(AQ*d%oT-1N9%I5E=Q|r_nyWwrPUnYZ7gU1@vw=3-y2w}dxJ~K zD9gww%XCj*ncov!Mn-uUv`@YN_!-gh5Yh1v(eaS(2|ncaIF~ZRrAT*hJ?UWou_gVd z&1(mKt`LqFg!BK-s+O>-C9G-*t6Bn9OIY<1R=q?aYvL7Q2o*2rfwM`S*V^ zqd1q~-%IfCCHVIe-Q)b3-{bok{{6Eq@$a?Qyx9r=?l7ZFkZ<}Hf%YQMUIf~UKzk8r zFT%$bfpM&{NO`E!5XvJIh4WN<~tzScKmwx0z%dSlmtr;GH`qI+TKqogp&l}3H(>uHohB@4xx-9|;%d%3S%_Xf)G({lW@ zLihM8@Y4$Xw1TyF;N>0cuebE(YuQuoFFN$i{6`d8i3Vt`ksVzCqyivS22y1pRR&UJ z_=@0@WCRpiy^H{q+d?bW;J*<^W-h~ye-UkJf9;{Q%QM9{d#fEN)xE(|J;7PV)v!$W z1j_uLAhUMz-}>r;x7uq5{_&eyV{wVHh8t^C?rX&o^RYw#O9Ze)080e0L;#-_{F9CO z${L!oMy%Kd-;Fl{C&InMUE8TMw4bOC5cL6~KA?Mo0l&vtO4OI0zVA-p-Nh+=x1*g} zmH}y@A3JWwZCh8H~*<`YK?t+K)(d^OF+K_ z^h-d$1oTVr;}S5BHAC@ z^LqmG$k+3_2JyukJArsdJGsgio;Nk{-*LPzuEBL*p@z&WR=S?g4 zZ$E;x#9d@sTz%7hW<5s!nr)Fu$zR}$9Ln$4y^Z&mPT#a#e=@2>&i*GytFvBHX3{m=N+L7QU!nJRb%9+A zOWBM3+(h8C-||#mQ>m^39?5I>Ti>kk-@CXcu8LAksiD+T>L~TDd%|ouzsaJoOSN5B zcB`=|wA_uByU}ttTJA>6-DtTR54zjbgltulRac%7uqkEjwjR8p*6z9YrntJMySXB$ zEP9dkqzMnRxY2$OYq*cm?_>1)82vs*zmL(weXzv#NHvGH9!9FRdt&^J_sTrYzZ5g= z?7D})EWAfgD8I*_(0GsTaoy|pq}{9cFTa;q?eIP~Tua*By0`ppJ)!Y#e}d~Lx+m=? zeoy&N_$$hvprwOrB)%X1SAyYRNUlwPthw?Uzp`h%vL{y-nKKy71%tU@Fc%EwVu86} zG#89QR;X^88)n-wn*y6!yRK|oXH)bvNZpD?{sPmK_j^0M$Le5hCcYg?cRm{D5{+~9 z1lL{ugtWVKPx)PbPvc!g9)8#b`>)FTKQvdXpYB(Mm5Y`4va=%cUTd-}RqHCoLd969 z7z-6+p*eW*94t5|%sLC3icJa|)Z2Asod%miOCeec(Nc((Vzd;ar5Ha5$<{R$hG~7! zrj%vddWeTgTPu-Q)l^L6sl9hw$QMi2L{iY99{j8tdW z)%@$*D1W2k36B}qY$9(qkvE&jn@!}+A@b%Bd5rlrBCm+ZDrwFe(Hi3twfyf-oyAYO*MLDs77> zY^rREo|>jY?v%eY<^0~jm)vc9sV6v(aJO+p_XLjkJwg6k)y|`*LPoyUKK-3fxOK|! zB;xKQ;tGklLL#n^h$|%GikL$OaZCQ-o04@W`Wxu*>{gjx-&{H284K42S00!afN24k z7Jz91m=@r7;aHZ0VOeF@6_(XDHCC{+WYCz0#ym9Up)n7Qd1%bTlk?1Rl})U=x?0U| z3iVXmbu~hbO%XG-c0ES^p1Mw`_E|F=$Hsi!>nhL_(hB?u_}~0{?6qyXj4D?yNauodE=cEsbS_Be z5-+)7@epXTDCPBSJ!(H-QP)crvFd2N1C4i}@eVZJfyO(~cn7u(>8WnIBW#2+n_`4o zyRK|lXH(d)-mb^U-)T1pb#fb~<&tA^$uYU)m|5hQS>%{mc&={ty`aD*$GX12voon2Q5*W1+h zWjA4Qp>aAIr=xK?8mFUiCK_jA+mN2xrs-ieTxe6+u->k#5gKd?8&=vQ#K_-&R|$1; z8#c})4s(dZ9O5vCILsjq?;sBGt&{K2x-brB5Qj5}!x_Zk4B~JmaX6DW1o5u0Ve_9& z{6IPjq_aRe3#6xm^mLG(j%~vcey}O4&4vwjT_Id)BYcDGBQmm ze~%5zGl|1Y;xLOi%pwl6h{G)6FuQAPxW?XRG`OaM^fZv32GY|&dKySi!?xiFmxLi) zW!Dvs)i!mDTn{Z7G)_h1R5VUS<5V}d-a{UmTe+bS$1m_=u^AExKhs4ki!(t@RWKrsB*w&-2h8A_ZU~1LTcpDmTL*s2| zybX=Fq472>8`4wVbX(X6Wj3X*hHX8JP-pk3tD)7CA$gnn$t{@nLt^lU#NZE!!E|CU zofu3f2GjpN7A(Jw7`%-byqy@lofy2G7`&Yr1m~{Eqxlb67OZjI3eLBJ^R3`~D>&Z@ z&bJXkZ7A~OtD@;vlOKHR?7E78WkHIn06! zZHf`d{(u<#0Wo+RF^FINTdst+5QDc6 zgSQZaw-AH35`(uAgW%l-7OYG^Xj!n%bt5?62+lWx^UdIVGdSN&1cl@KVAG9l7HqKV z3g1c_-)zCul0oAXG)_U|jcB|PjW?q4Ml2iBQ{OZt%z}$-3JX@Y8==ak)RoYZA0auL z`pGSrb`vpp6ES!bF?cgEcr!70GckDczsG{*HxPq25Q8@ogEta`Hxh$45`)|ub%h15 zdB?I~gKH8vPXXsC;5-GKr-1VmA}Ac+k}!O$?7DRwwD@uaQ>%`~Nobse#z|;F}T0QDIXw?TxE}(vL3pP$B2B#2%Q;5MS#NZTS@CIV= zhJTL*U6Y8xNyOkJVsH{MIGGrnObkx$8VlNAK7jK?aGnUx6Tx{RI8OxUiA2!Eum}k> zSridcW7m}hYi(+lU}|xpaXcEwqj5YM$D?sP8pmVVke=$M@nIvB*%Twx+I2NTolU9h zpe1vOTnDM2+=6KniNT4);6!5Z`^4b)iNWs^gWv!6Sg?FNF*u$WoIngtAOoVfpwM3!b;g}To~3BO%_E@on2R0*V`0WH`sN0 zbn;?5v`=~8b<*d~r$*%o*`i^0dEi4u6{Fx{kbc z9eL|I^44|at#RZnR#1+Qc7;vWY%%AnpXPf2o~3^jX0^f8Pc?rDqcS*kg-^)OOZo8S4%(`26E5!g72tT>vi zIGU_DnyfgQte8etB;xaqJ_GeZ;YkI37hDk0Opop``<_#J^AWzH~{t{5QKk z4vW4jS1M~yW$me~Jr(3r!6p@KQrpn4YO?AI{eVq@NsV1sHm$WO(64JsCHmCgdbOcn zFa7^dqc4@{OC|bJiN29U-$K*0Gj-xN!YBjFmSZg@e8jiJw zW3AzMatfZDVveIMRnauO&4zV$U0JH$rqFT~TCPINRcN^iEyK|=9G?iu);3)grgfoB zVgGu&uCzATl)7dP7f)*!eN}CvRx{TcN-d?1Qcr21RJy`Ft*psf4I|asbv0658|5!o zJnf=yIMH_v(RU5ecMZ{Z4bhiE^fBJoh`y_dzN?A8tBJm=iN4`PA8RTH`O}TQ`{nEY zKZiwMo$E^0ekE(alC@t2@>hZURbXQw&dTeWt_(x}L7Sqd!LBPzD#OsPYPyQ(`*S<= ztEK<{Y4m-M==&bg_dTNTDx&WyqK_3cUez_x_qg>A^&3QAxYZh5!?4!nSnG1Ebvf3$ z98bO+Prf|NQYB3mg{7+Oy0TQYO`&BNT85!z7+Qv*Wf)q9;S1s$18-P)~KJ zM_v1@9(C;-CZ5*L{&hAt+AqiBE@$*B8U0E|zmn0fWb|-PTV&6Y`B%2{w5m4BUw(zm zvt9Ikm*~5k=)0WgyPW8|oanoP=)2-;Mc*)@Zy3=xjOZIi^nI7;`!3P<-P4c0#s9+| zrYS7?s$D}^_Yl@S1k{Is%MfrG0xp+@*|Dr?NSiHc?YfnPtRA!sLdzhu3_{BwvuUbBZInMv@r2v4dL-YjKP=7+&P~B5L)bD8=s`r<%I-f-w2jLBa z@rJ>8!(hB&Fy1f(Zvgev&7!?u0F%Fj*|FA@%-WM#dopWJ2Khl?GYD)fTv>T-Q*s#k z3vG&?db_SLX|O4E4Fi4ioBOssOqE#Yt6B8_#eLsEVrC#QGmw}WNX!f(W>`TvzS#x$ zeI*0mHxbl3+QW44*AQ6kf5WU+=Ssq2NmwiiizQ>RWGt49H(Qock&zT;wFjFlik=3$ zuB=uWX0@uOWUSWyJIQM4|EksgU)=W%;MzApPiP##wJ(`#UozJ|R?wK-HCB7=Y~3E9dft8QKULOs=?9(C=rdepVgE1q`Twa@BDdmYTaUW$vnhZ1w`HE;IkWLnvRxwCE|F}PNVZEP+kKmC_wBEfGhJTd*h?IHiDNHu zd?|5!DRF%1Y3Iz6eShWJ7oIb#UGc0to^{8AdOWzqgG)TPc*5*h))e1ni(0#`>{w@0 zXo*EjELvjG5{s5tw8VpMNVcXaHcV@UO@VHmT~}J`ZAxAHVkOVFvtwo3s8ucxw(~H$ zhtWNZ?qPHfqleEw&}31JRAblGNVRR0KTYw3+p#>JYhOIqz67p)30(UUxb`J*?PIL3 zaqWx68{+VWIJ_YaZ-~Pi;_(JhKh0}jN&0L0>JbYii#8YR+nQL`P^LdQZ-M{GtqX>_ zYErJO7V_o@%lyzmU5gW?we~U)v8HkDhrc(XM#!H$D`UOqezq;{~;idd*O*ww| z*86n%*P9%U`|W>qvqX#IU)+p~Uw_2kKXBw{u2my>23xTB7_G-*BDIv}0{+F(`08VN zLf}~QlIDHWXMCXg=hB(!swa4+5*V zF5q8|DN{Yp=7I?=d>2KaqVAfOkfmvEP19(|DJsq`bZ6w|=4WOU=j7+Pr)T8kX49WDJ$H7|%q!iq3JUX! zvonif*Su!qrS8#+$(@;>mF=F9otIsxWYMf?H)Ry&<>bvsa!1}0<yl@%x&|%{>IMp zP9E2J-cv6PpDCK1TkIZ*KP6=0Qi}2^O5vYox-E8Bf#LY4?P zF3`WXpYsKjl-aGVhdAHCxu-+Z0-W8PYdK%WImr2D&f7TWaz4U&3FmQhT3a`AKKsY5 zt@}CO%GnvAX(gP!oDI$sIbSumwY8Y@D$Xl854o$gbqnW-od1_|)jf=-qyIj};kpzwzh8P9KE2mRdZ_E-i6GEbHoGiarXYSwe>;HTNbyr201r8)Y^K4^LEs5%lw4E<)93q=SxsA4X&T_aZQz*H# zUC3EW?bRo>B4YGB$GEMj+f#cdi*=qiA36?|h%UG^Fy zhKG%}44y6UOg)b0MvF(*Cq5-Uw%p=-_;iEY!;E`u)`LrjHl z621iXyB*gGunY8uoJ%7GUj1@i3G8;HzLNSz>K|m?BA0^P-S}v{7&5ij#N)-fM<}t0 zAt_UCF8tGff=`;`6&x>DXAW0zyxdykJ|_kwMou)|eJ2@DVrbI5*496pV{BLyD4QH=bt!6=%D3IHO+jW=S!-(|b!6O@zf8q^Zoy6T z&V{E69*?<>t5B zQZ92kR9()|(9++H(vxzmm2qfqRNcRGh`MMct0k$Kn$x?82bn{mEQ=>slu z$gh;Nkt45kd(+0>aH)In(BvV>gR~KoXfDht%ABJ)=ZP3I?ao8d5MQ zJws~KhZGD+&yt@^X}dcov#8LlOwZ2C%!ZrBS+i#64lWpk5_O0@%r%HbxVOc&vhTJJ z!8bx1%&*zszC9ANwQnB)L!{V9iU7B8MN0{L@p90 zIUb@o9ntG(b4IxS!7QClmrp3C>l!&ZqMqRtc{@K2PhYvabVfuz%_(v|E--osl_t#aiTi=}!EXJWFs!M<$7`XxEi;az+m3)CW(AevV4yVuT~kkC_T* zWI7G{xiKT8{wsd;^UjuqLAzv(gqNZDKix{6xGeZL!k!rnJdV#6Es{ z{DrnYu9ifZ!`sZpb=aC!fDYFey`Se45%p6M|MKi#LO7#p;B_5~8IF%|!}k}_CqEGb zX+L`-KNq^99MOxYM87Gl(GF8(bd%`s<}h_e|5T{%j$T_iJEPwh&K{0);zeupE7I4~ z>^oP}ub|T*KM_lXO^mAlLfYgfVzsnACvCrxHu;J8owQAtHZiP2ej;9zHa9cX|0r$p z6Y-(6{apC|CT;Q)(IRa>W~sV^ABX%z^pKjEF5(=iJtnn&QhQozmr8A$)P_p!9jRR{ zHGwrEO=<#1#P_9ECAA+&ZG+UZrM5$A`BHmNYIjNPbE)~ICbo=_h>1LxAJ@golY1;; z6sN177$|BNysk@nub>W>oLu*w^$hiM`ndK*8qhuW@bi9mRsBAaAM|j7bk7a6e%Rw| zs#-S*A8Axh*IVl*^3tPdm)317w3x?o{2m`LXdl;~#1EqWPM_y%8jih_k5lbw{W6`n9P10FG#1FNswxYB|5r zqoOb1)HA9l-O;0atmV{)=aZbe{Q{;fRIIt3yAM^-X}TzKM(QiMrfFBeB1v!-brlpB zNpg|nOwJK!!s_VT&?{z`1gkHR0(IS#Hz1KD8 zjXg)2ahC6iDo1av$0g3OF?4@dlauaICuh9YqsQOb7Gsq4&F>Umvc^y{!pFgCTQ<;mjC^(!_A0=qziRYIG9YWnt62=DY|V1E1YC zxFvE z{{rcdD2tHYOoT**el|Z5{rGWu`H56~1E@s}<;OJyJ{evfHlA>Jn5-cpR3xaM9g4nz*(#n<>U=ZpPrllqGLTboq(fLR&S za<0zFEf~t{)B&?{iZTWi6=Y{#J!H_}D+Ui4JX9D8GiP3{cCNEBre|fETU36{{i%Dv z4EKNuL)-(3inFeskvALF1EzDn{E7iNdAT`x*^slc3uj~x;Dzjf%zWOSX5jZs*J#E(gD-+^3joz`J(~W+u8g=voSM&)+}D)q6WSJ*@cC9`4AJwj^ejCw`jmD z-q_||os*YSoRg6|AbW0hrZVT<*@gL9Ub;Y2ba%)uSd-SQ?4nF*HQ_V;$TYvID^S5O zE2B8Wa-cR8+j&w}u9lvfpP#E)mJolly(~LFFGOUBrHf}4W@luj7iH&8XAZ@86=Zj0 z=uct^<8!8F=S;93kjIw@$(b5F1^Goea|dFOBBAWF_)3_9*?I7gf#(b)wq}Re3AEyY z6gh|Un@Kvapg6aEhBn*P@6aIwl&%3p?ZBM8%-q>o*`{_)T(l^8CKJZM#RPP5UWk%3 zEF?3OM$7H3YIZS|9O(u_e#PrlOHMJX1%Tq5%mIbje4+t)qN7+{o4JaqyK7BTdo&nz z>&{o6L&%}?KRM)igdE&)sk1zfFlqK;9P*q(4qZL1&@}rwg07xEAkY23*{?3U>bZnT zcT?^1Y`~=DDTjH_ZPM(GIAlvGhpwJnaIKb?_=-M5ou~ZFrp@R$f2vJE1Gt58*M&?$!ep&rTAvH(ee}~ zbm*FFu|kKgo(hH2_FH_jO;=Bg!u#dvMCj19i$Vl7T~lwA+uC%kpJidQ$*KLlwI@}v zx0|y(H8N)$>K6^NB{Pp6+Egm?e9NY1S~WR|zWn3p`;Ma*K)++jNAUDY^xL#N&3XXZ z2R_#8wb4v zed5WY?=t9>(BhdwkAxnEzG2Yze1$fT9@=$O1AKci+UlPQy#v}~(Q}|H!}OOxSBKGy zp>J!W&(WTMo*G8W6CCkBv9tsKlWz)oc5`UUE&VS-S3wJoGQZ>T-bw$Khee6VoAICs zeq{Y}gKWo}JXJKHZU1-R|3{(i_~JHE>%)F}3iFY}f&a_9@vLZvdUACZ;}3>DV8yRQ z&j@JEvZv5fp!D*^6i4qa`Rqm@%O<#k3ze{ z^wmS#@z;l^qU)gT_!RmjXnVXqjQ0lgAh$#NjI-$9$GMPuTUnRT@)#l)drw46=!4MD zL2tKcC-WZ^HvZYr51r#6=b8MMa2|s`+4_t8An24Z{uJnoaYA{2Fa6`7!{>JkbUpY^ zwdCa)MG5Qg1AQjzFM_t$cV@&nS_$;TF#QifOTHBUK9hX;1oYIf{&mpdc*?gW67S+q zGM|mm2k_@&ilve>HT-e&5o@LN5vHza9Fs2OZjb=o9&A&|eVLw!aiW&pi)38B+T1gDwces{*<* zOy8r>c0NBd;%sgJLmP##9h$oH%GcuOe$&Uwx%uo$XB2R~KGD@Vv#_|Rc=q(^T&T0M z`Fc@(UYTAzD?O82n(QL>j9K~VGjj8%W#p!373UYSsh&MoW3N?^n_Zlp#gp(8a->gZ zxb%#|!i>Apxoa%EOPgNEUOhc)_N-ZVAreM$3zk#dj&)pqe!=+cqT*z=gJEVfhrm>n z*Y>5JG{`4kJRx)QXACj^NM~$)M#`q>_>1pF8q;d~9 zVf5(9qo&vrj4{11JDa6x8O8ZIDQV-zrjAVK=6k4CFuPc8{=%Em)8*dWy!B>oIeDSZ z%gnbH>3rQfd0hI?5XI-Gkm>2ElP6pAFDPUaI6WjvZ??K=N>88c8!=@>dg`dOvEyZ- z>Fr2`pA0Z5T>teqrVr7S%1POC?8=PEY!irP*vV{&%!Se#ARit^KEX5?jYH*K0OT;p+fJ+rcB;Xdscvh%XU z>ZlikP_w+z`mT7wbs<>!QdhxhE=f5|dQN6W=FIGN8toV>$OrT6!uXH^K1)UcLltDq z$S%sc`#8C2MMc(n?GK;B^@{DoRJAim>Ie+N+=+UC(F(Zv&OgqJrd&VL@&zrq=&o7C z8Phly7nJ-|6lRC=hn5^(52YYAG*1Ay6En5V z$VYXNSuX-XEm{4@EhO2BQ6=7!Gm47~bEeHMCJiQMWlx(ugDjPihY@U2J(;q*rcEov zuPsWRjo5Wyva8aJwF=e6sgpk!z$aHTwgH;lHx)y~hRK>&I!%kCP2Rf-pX{$!(&46V zA6$0S@g08Uu1WahK1(i@bfnw@`mvs?_`Bf?!V;wE$=i!T)WgSx)MiLOC6yxYq2)X1CDcV9S6|g9_awO#nS;oi?~2WJK&nI5AmvVq z%_sYowJ5r -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BGE instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BGE - -// No specific optimisation for BGE/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, BGE instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for BA instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for BA - -// No specific optimisation for BA/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, BA instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genLoopNest(h2_insn_t * ptr) /* C compilette prototype */ -{ - /* Code Generation of 58 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 6, true}; - h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 7, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; - h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; -h2_insn_t * labelAddresses []={ - 0, /* h2_prologue_00000000 */ - #define h2_prologue_00000000 0 - 0, /* h2_begin_00000001 */ - #define h2_begin_00000001 1 - 0, /* h2_end_00000002 */ - #define h2_end_00000002 2 - 0, /* h2_BA_00000003 */ - #define h2_BA_00000003 3 - 0, /* h2_prologue_00000004 */ - #define h2_prologue_00000004 4 - 0, /* h2_begin_00000005 */ - #define h2_begin_00000005 5 - 0, /* h2_end_00000006 */ - #define h2_end_00000006 6 - 0, /* h2_BA_00000007 */ - #define h2_BA_00000007 7 - 0, /* h2_prologue_00000008 */ - #define h2_prologue_00000008 8 - 0, /* h2_begin_00000009 */ - #define h2_begin_00000009 9 - 0, /* h2_end_00000010 */ - #define h2_end_00000010 10 - 0, /* h2_BA_00000011 */ - #define h2_BA_00000011 11 - 0, /* h2_prologue_00000012 */ - #define h2_prologue_00000012 12 - 0, /* h2_begin_00000013 */ - #define h2_begin_00000013 13 - 0, /* h2_end_00000014 */ - #define h2_end_00000014 14 - 0, /* h2_BA_00000015 */ - #define h2_BA_00000015 15 - 0, /* h2_prologue_00000016 */ - #define h2_prologue_00000016 16 - 0, /* h2_begin_00000017 */ - #define h2_begin_00000017 17 - 0, /* h2_end_00000018 */ - #define h2_end_00000018 18 - 0, /* h2_BA_00000019 */ - #define h2_BA_00000019 19 - 0, /* h2_prologue_00000020 */ - #define h2_prologue_00000020 20 - 0, /* h2_begin_00000021 */ - #define h2_begin_00000021 21 - 0, /* h2_end_00000022 */ - #define h2_end_00000022 22 - 0, /* h2_BA_00000023 */ - #define h2_BA_00000023 23 - }; - - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x7FF, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000012); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000013); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000000); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000001); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(10)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000003); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000002); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000004); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000005); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(11)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000007); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000006); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000008); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000009); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000011); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000010); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000015); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000014); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000020); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000021); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_prologue_00000016); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_begin_00000017); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(7)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000019); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000018); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_BA_00000023); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc)*4)); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genLABEL_1(h2_end_00000022); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genADD_3(h2_outputVarName, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = labelAddresses [h2_begin_00000013]; - i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000001]; - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000003]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000005]; - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000007]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000009]; - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000011]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000015]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000021]; - i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_begin_00000017]; - j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000019]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc)*4)); - h2_asm_pc = labelAddresses [h2_BA_00000023]; - intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc)*4)); - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, resC, resD; - pifi fPtr; - - in0 = atoi(argv[1]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - fPtr = (pifi) genLoopNest(ptr); // Generate instructions - resD = fPtr(in0); // Call generated code - resC = in0*(in0*10+1+in0*11+1+in0*1+1)+in0*7*in0+1, - printf("Result C : %d Result D : %d\n", resC, resD); - printf("Generated insn # %d code generation time :%d\n", h2_insnGenerated, h2_codeGenTime); - if (resD == resC) - return 0; - else - return -1; -} diff --git a/CodeExamples/Mult-With-Specialization.aarch64 b/CodeExamples/Mult-With-Specialization.aarch64 deleted file mode 100755 index 0e59760f19f933831209c0fcb9084bb23b5f794a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43968 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%0Db|0L|oQ&rsLUE#G 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genMult(h2_insn_t * ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genMUL_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res; - pifi fPtr; - - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 & in2 - in1 = atoi (argv[2]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - printf("// Compilette for simple addition between 1 variable with\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = (pifi) genMult (ptr, in0); // Generate instructions - res = fPtr(in1); // Call generated code - printf("%d * %d = %d\n", in0, in1, res); - if (res == (in0 * in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Mult-With-Specialization.power b/CodeExamples/Mult-With-Specialization.power deleted file mode 100755 index 7187df068ab3f7f066a0debe97737838454486b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78208 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 T3hDFjey@ -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_POWER -#define H2_POWER - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -typedef uint32_t h2_insn_t; -static h2_insn_t *h2_asm_pc; -static h2_insn_t *h2_save_asm_pc; - -static ticks_t h2_getticks(void) -{ - unsigned int tbl, tbu0, tbu1; - - do { - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); - __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); - __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); - } while (tbu0 != tbu1); - - return (((unsigned long long)tbu0) << 32) | tbl; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - -#endif /*H2_POWER*/ -/* In memory instruction generator */ -#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ - } while(0); -#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); -#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); -#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); -#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); -#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); -#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); -#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); -#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); -#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); -#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); -#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); -#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); -#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); -#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); -#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); -#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); -#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); -#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); -#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genRET_0(); -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/power - -P1_BLR__I_32_1(); - -} -h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (power)\\n"); - #endif - // MV const in tmp register - P1 = power_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -// No specific optimisation for MUL/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/power - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - P1_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genMult(h2_insn_t * ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x780F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = power_genMUL_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = power_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - power_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res; - pifi fPtr; - - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 & in2 - in1 = atoi (argv[2]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - printf("// Compilette for simple addition between 1 variable with\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = (pifi) genMult (ptr, in0); // Generate instructions - res = fPtr(in1); // Call generated code - printf("%d * %d = %d\n", in0, in1, res); - if (res == (in0 * in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Mult-With-Specialization.riscv b/CodeExamples/Mult-With-Specialization.riscv deleted file mode 100755 index 2a6a6a009ea4c5d988f3105be86fe46647641d81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29172 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%0Ad;3I` ztel)QiUNWQ>E(SM##Pq`cx$EByWJ^iSh<6xkcWw*O$lg9KvM#JmT*m#sQ!&0Ne0CITM74XCD=bE zB2TfmwXnCfu(!3MtJu|z}xM$w-VS}3GA&zl=L5ZBeKl%QBoCEWLvpjcnoFJ_ug3l{Q6`#Ipjic)RiIe~npL1# z4Sf>6B(GBa+bTc_1abeiiu<=!*gqOkqhfEXVQ;HpZ)-%!y2c}U*TCM^z}`x3x88iK zU~eD5-aZf|?*|^q_W|r}HSCR~?U=nSg6#BUawTM63E5YohENI`NjhmwK&3ve*5c zc2W5Im8#zF)|HR`hlsaMO-qivCN3ZH8a=hFD^EI=Fl+TJ@x2*yJ@0LqJHW6k<H_I@jEbuIo-V~$1f%L7cE8lw>7QAwB5#G~(4)5tdhv&inHFLW1u9)(k zm?^fD?-1vvXYM@7=x-V-#@3b3Tlwl!X!Cu@((rr3qM_ideDr%J{@0h@hIiGRq@||V zrA^TxECm!lm|~VTar$w9mU-}I8vhH433cUbmJ$SAHR0*%+j!Rj&yzjzdgOSUX1>k; zUI%|G4Et%)s0{ys_TClaeZccJ;qN+iNH=Eo@Ut1|-4^q|Z^c_p^hOi?eSBR1OcvKK zIm`H{ajYZT80W&@zsF@UX2jo=BO}L!KeIRTKkB!;a|-f}lkGXV4wUEcKiq%R82Gz> z;G31q2aLlwk}GTNOv?kR|07~#lA^t=)|9oeIt1q9o3r#Uk6^1yRiI(vG^2sS1z>rqIP6qlJ4 zm!k*$uOrNdLmp3=xiP(%d5wR8V7{tR6XCZzC@f^gv5tkr-YfE!;4dMfc8xXUt&CN!9 zqrr`MIO0u+a}nRWt+{zV;XT_+ETNVrC8S5Fhvl@DMu>0T1zNDp*TUJAl-@}8fk=4NUp>%Al?q7C8HXBPlqLhx7F; zP@*)xh6AStIBo?eh_A^3zNoH3;KjlghAViQjJm-=?Y#w@;lP>L2IpxNhveG;94~Md zs5mY1%?Zdyc(uSg4?NzFsgW&wjR~;Dzd00!jyMIpqp%(5zC?I}6gyY^AANBMsaLEN zIYEh#x+8U8>X#%peXA%1bpPW+pV4`F>RZx*74@Xw6vzQR|5QDuzjDxXJK2ql?t1MZRt*dZXd?V!fUkmn|9hWf;A(J zseR4O2}pxaquTcqA(D}F&=1*G;5-5xNvS(!xTXTGxG1IO6wVR1f708Fph>81ZvK@b zN7YaCJy;Q>s*S!&fd9nT9h1Y1_D+FrxU=Bs-fk2P2ZR>L^Wd7-A}?&tuW&vYMKk3y!1yX2isEJ>p8hw{nrZ zL}^4IKC}yUH&c2s+P~RA-`k^$?iA984t>;U#uw}!F!mo{Nw)N3L&hSTfAowAwDQnL zg*fs3yPV|0{uI@)zIFUdW(u8F(iaJQdx&RpiRgofd@)FtKzs|+b>k5w zQ9*);57j9I)M(@uklaT|bo~#4UI<%M-4OW8mhQ}!qLO((j@*Hl0)QcuX zy)I-eqLAgd3Fdp_DE&K_its>>T%^0|L-5@<7BZ8H6YfYvqz?#YAy zA07#!urBBP6g8l~u3S-^hC-AIZ{05lev@rY`D(FO1E{maM-eHZD_k3-UtW})As>Clax zehWay#Bqpt8}pFhZFFG*W$GxykOWHc9i#-h>HbQ2O_cWm<qhJPh(#s22r>D_uW9qznBWvJ6*y{1t#cbQy3B zP0@p4BUt2oha!P)x+LWHpe@zChEO5wO(ep;BGfQJsWR*&)gLY>b%y6TO8Cd&Je^5~}fJLOHLJnC41 zZo0jcX9TC>Hbkjvpin>nMlTv@CRBuYHrPKqI z+D@qflsZ7EL6jo3>e4Ai>d-w&sU?*9PfC?h%0a1}lq#UqAxgbOsq>WbP>T9eMyiydgf6t(*1>V;x+Brc7?v9OK2>=X7-7~( z8mlaH0q$XGVfP^F9NHPhVZ$Oy5JfTZWklhB0ut@MRo?DAjH<%YMXE?2BGPwJ*+8I> z6U;-J4~qN9xzN=Ov923Xgbnhxg-V+%Yi6cIy zvoJC8@w+m5QZ|g`F{(=F$|CycGon%ab4HOU@kk%bA|eJy;Jc12HDH+;&IraiI0APV6+CWtzI z7sA7kR&unvzD zPrcs(6lj#`XceQQQ6csqyX}pe-i%ua$Lot!=m6Xd^Z{6Eo;KL+HV-7V2^}8^{ARHv zxn6Q*ISO4#d|8vkKlf@G$C3&P-APlYIr7~(`AP1)!X%e7Gbx)s?%Ee$bp3g7GSfAU zKJ#lFGR~N6d9WW-J{il>awiW+woNE-W-(Vm=C5(C=(Ody3W9)qyR#7AgPn%;05ILm zm6QK4J|KFzkg?-!qet1sj7>`$IcB^q zHDi2B8~HAlTace^$Em5BYo765lUm= znn+o`Jr5t!rRK5H^i+H_tvPXOQwaW&k-ZdtW-G z9hBU!|G@sq{Ra?&GjqxyzG}_0PtM9zmZ!KYYg1$2Y-8Wi$;Q4ech;cn{AsAV?_|V} z4D6eekB>e(0OmQI*^a(=pwKt70O$Yqe76g^&Vp(AS$Hgf7I4hpcXECK>ab`2y07}x zU>q^?%*=wkJRB9H8sPQCM~L$a0F22YIlr4!MJJ@^K1n&+Y4Y(UHl!^JRy# zfaTjrHLjOi`USm-+$@JHlX4aHDR!iEKTmU|LWfy)w_P=$fEHU>QdTarr4|(AGPNhj z-ZU$76y&!6cCsY*6sNb@a%L^sz(6r?ob#7n2|2(gkc&83|~f za;SN&=hg8vip)7+WCN0!)8&|I%XDGf*t1=>N%)v^p!5+WVGcI8J-dZ-e8*W6DUh() zi4RgDvt^9N_(eb3rn&Hp=>Kc;x}GJqYkk)+uMYaUwmy?-J`=j`n~yJKTQV7N3JY90 zFD9WwTm)$`*-B6a)AE4>5Bxm7tBwz<2hcFk+(`%&2jeSFI=|4J+uB1b`TUO0u`3^E z$EZ!p$t-4t8TeyYpKha>E3IL&{XmUQIgONaRp4bcj1y9nZ;e zLs}@nos-$u>A-ix0k(J1xAf@}`Ocd0Z`Ug@pQ!oyg92kIM;Fc==)#VR$8-*%z;rsH zoKGk)ol@W#i+X+_@>2&qO9{Yy+U4gE3Vt}pr!xTsrqc~&&#k~%8{wiQAzh;Sb$a@q zz5;jQ@f*W5SUJO`^A@EXi$h#=-a?niPfV~-3&7oYzIN6i@~_DwYodmaRTC~cSD{Pf zrz&_B6o8e}mx%%R4vse^0MqG9%Ox^eVzpc%KMe|owWm-@p2$y$g3I~Sr$C0t?hB+T zAu|3%B#U$Wl#xKFj6~X=!NvlC% z!_;zm_VpTINrh(tUK~{ae85YC;J*O=RRHeEJ_P)15d0ZnvOnr+0bio81iU*;U<=gx z_W_<1E^s{(e{J=B5aqrns1l-A#sdd%Bl%CGNE>f-nyAN+*X&<_{o_$7|E&szrVBFy z9s_>p5@7!i1C9khwBqfK_J;s2SI2L6g$jADE7*< z^d~q4a8wXJ?YM*ac@A(c^f^(*&jCCg@HkT93qh~x zBNuQ?tib4*AK|+JPYkMW7GTX^chmL22Croy5VQiLAJVWCu-F&>)g$BF0<1c-3o#$J zH~VHf-7fdE$&)b=XF2e84S)T|=FYQaVn^X{VNIA-p#26%mb<`-Mf0>58P-yG`@`+X z!YOyV7`Dl1&SrNy?JwD|D|EiZCOfefw`EPs%XF;DRAN~Bwhjil8urxAtwv3xr`gb8{@A?Q7Z7OD8t4M z8JT8F8)dcG81{;zho)Jd8k=StkumC*L(wbPEq%o3RP6ai4;wZvZM;T-HYPhA4v5Boh9xEN^C<(gpJxfq`pK`ev=lz5JfX1R zeJs2nWeWnwjj+)Vu%wO~r}D4-kV^|GN*#QYWV4O44jDhhmYSBHF^UAWwF0^RsDZJl zFaV5v+Lo;RHq2PZ^I9T%92SSlPtF9l6Cj!pT*FwXqaXiCnqXYmBQ|d8u>#bDpR&Pn zQ|tKbaSnF|3=TYIxe9Dk?D<*PF)Q8Gs+QI}8yGRSGE_z?N42WGsc*WC{$-0`cpr=_ zPGLIu=WbdxppB})FWUr!#LHZ$Am}G}TGLH(xm4-2SMh?&`ET#ER7ENWw;0(F9ChZ? z;8K6hCz#A;8$WWW+Rx15dMVFspM==$RN^UG3d?>6&S5Nk=Q1QUqc3e2E!aF*rr2Fm zm?i6_d=M+K+o_a1?{K>CCSfbUhBE8`?3O~XV{toP#NAoIt;yn;qWTBgy#^p=DReqo zd zB%VdGEgl_X(~gJmXpi+Q5>-gku8Mf0`e+^;ia^sa;nB0@jFQh52=XhSu#DL@FGq1VW#E$(f%SA zfp{Q#T5B!_9?79yBm;%12pS%(Q3_GfTZ1$#r9OgQQ1OUAzSbFv_kIXaFVYKLzeS+> zs7U$EHRbo#0P;)2qsLzw9_=097>3`N(h5Oy_IhZALlij__!0PQO7{ujV1*bYiTO01Rnke zF5-zUI>`^lyYorB8m0{nlxt;ox54|5rx{zK6$as%+u$`!z>_IMk-;r|6W+SErNg`nZU7TS;j2i6Bs8UpoO6at;La9cr4*TTtosX*&gz*^OG RDiVyB@N33KYlT60{||Fa8chHI diff --git a/CodeExamples/Mult-With-Specialization.riscv.c b/CodeExamples/Mult-With-Specialization.riscv.c deleted file mode 100644 index b6a8bc2..0000000 --- a/CodeExamples/Mult-With-Specialization.riscv.c +++ /dev/null @@ -1,755 +0,0 @@ -/* Begin Header autogenerated part */ -#ifndef H2_COMMON -#define H2_COMMON -/* Common HybroGen inserted code */ -#include -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_RISCV_RV32G -#define H2_RISCV_RV32G - -#define H2SYS /* Has operating system */ - -#include -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -static int h2_riscvVectorLen = 1; -static int h2_riscvVectorWidth = 1; -static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; - -#if 0 -/* -https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang -*/ - -ticks_t h2_getticks(void) -{ - unsigned long dst; - // output into any register, likely a0 - // regular instruction: - asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); - // regular instruction with symbolic csr and register names - // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); - // pseudo-instruction: - // asm volatile ("csrr %0, cycle" : "=r" (dst) ); - // pseudo-instruction: - //asm volatile ("rdcycle %0" : "=r" (dst) ); - return dst; -} -#endif - -#if 1 -// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h -// HW counter measument -ticks_t h2_getticks(void) -{ - uint64_t result; -#if __riscv_xlen == 64 - asm volatile("rdtime %0" : "=r" (result)); -#elif __riscv_xlen == 32 - uint32_t l, h, h2; - do - { - asm volatile( - "rdtimeh %0 \n" - "rdtime %1 \n" - "rdtimeh %2 \n" - : "=r" (h), "=r" (l), "=r" (h2)); - } while (h2 != h); - result =(((uint64_t)h)<<32) | ((uint64_t)l); -#endif - return result; -} -#endif - - -#if 0 -// System level clock measurment -#include -ticks_t h2_getticks(void) -{ - int res; - struct timeval My_time; - uint64_t tick; - res = gettimeofday(&My_time, NULL); - tick = My_time.tv_sec * 1000000 + My_time.tv_usec; - if (0 == res) - { - return tick; - } else - { - return 0; - } -} -#endif - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - long pageSize= getpagesize(); - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - perror("(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /*H2_RISCV_RV32G*/ -/* In memory instruction generator */ -#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ - } while(0); -#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); -#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); -#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genRET_0(); -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (riscv)\\n"); - #endif - // MV const in tmp register - P1 = riscv_genMV_2(PTMP, P1); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul & 1 mv -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (riscv)\n"); -#endif - return riscv_genMV_2(P0, immValueZero); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return riscv_genSL_3(P0, P1, P2); - } - -if (isValue(P2)) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (riscv)\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/riscv - -RV32I_RET__I_32_1(); - -} -h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -/* -*- c -*- */ -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI sub (riscv)\\n"); - #endif - P2 = riscv_genMV_2(PTMP, P2); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/riscv - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -typedef int (*pifi)(int); - -h2_insn_t * genMult(h2_insn_t * ptr, int b) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; - h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0x73F, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - riscv_genADD_3(SP, SP, intsValue(-48)); -riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); -riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); -riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); -riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); -riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); -riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); -riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); -riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); -riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); -riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); - r = riscv_genMUL_4(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); - riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); - riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); - riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); - riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); - riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); - riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); - riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); - riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); - riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); - riscv_genADD_3(SP, SP, intsValue(48)); - riscv_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *) ptr; -} - - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - int in0, in1, res; - pifi fPtr; - - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - in0 = atoi (argv[1]); // Get the users values in1 & in2 - in1 = atoi (argv[2]); - ptr = h2_malloc (1024); // Allocate memory for 1024 instructions - printf("// Compilette for simple addition between 1 variable with\n"); - printf("// code specialization on value = %d\n", in0); - fPtr = (pifi) genMult (ptr, in0); // Generate instructions - res = fPtr(in1); // Call generated code - printf("%d * %d = %d\n", in0, in1, res); - if (res == (in0 * in1)) - return 0; - else - return -1; -} diff --git a/CodeExamples/Multiple-flt.aarch64 b/CodeExamples/Multiple-flt.aarch64 deleted file mode 100755 index 5bfdddaab4100ce20e88d390e8ccda8490a3f8b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52288 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 -#include -#include -#include -#include - -bool h2_codeGenerationOK; // Does code generation fail ? -typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) -static uint32_t h2_insnGenerated; -typedef unsigned long long ticks_t; -static ticks_t h2_codeGenTime; - -typedef enum { H2REGISTER, H2VALUE, } VALORREG; -typedef struct -{ - int ValOrReg; // is H2REGISTER or immediate VALUE ? - char arith; // int, flt or other arithmetic - int vLen; // vector len - int wLen; // word len - int regNro; // register number (if register) - int valueImm; // immediate value (if not register) - bool dontFree; // if register, don't free -} h2_sValue_t; -#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) -#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) -#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) -#define immValueZero intsValue(0) -// Usefull macro instruction to simplify instruction selector code -#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) -#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) -#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) -#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) -#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) -#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) -#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) -#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - - -typedef union { - float f; - unsigned long i; -} h2_float_int_u; - -static int h2_log2(int value) -{ // integer logarithm - int log = 0; - while (value >>= 1) { ++log; } - return log; -} -// Print register map : F for free register, . for allocated -void printRev (int value, int pos) -{ // Print a bitset in reversal order (recursive) - if (pos != 0) - printRev (value >> 1, pos - 1); - printf ("%1c", (value % 2)?'.':'F'); -} - -// Dynamic register allocation handling -// h2_regSet mask : 0 mean free register, 1 register set -// 3 2 1 Bit position = reg Number -// 1098 7654 3210 9876 5432 1098 7654 3210 -// 1111 1111 1111 1111 0000 0001 0011 1111 -typedef struct -{ // Register allocation sets for - // int, float, vector of ints, vector of floats - int intSet, fltSet, vintSet, vfltSet ; -} h2_RegSets_t; - -h2_RegSets_t h2_regSet, h2_regSetInit; - -// Print integer register set -void printRegState(char * msg, int regNo, int registerSet) -{ - int count = 8 * sizeof (registerSet) - 1; - h2_regSet_t tmpReg = registerSet; - printf ("%02d : Reg %s\n", regNo, msg); - for (int i = count; i >= 0; i--) // Tens - (0 == (i % 10))?printf ("%d", i/10):printf (" "); - printf ("\n"); - for (int i = count; i >= 0; i--) // Unit - printf ("%d", i%10); - printf ("\n"); - printRev (tmpReg, count); // Bit set - printf ("\n"); -} - -// Initialize registers sets allocation -static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) -{ // See H2SymbolTable & H2RegisterBank - h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; -} - -static void h2_resetRegisterMasks() // Reset register set from initializers -{ - h2_regSet = h2_regSetInit; -#ifdef H2_DEBUG_REGISTER - printRegState("RESET", -1, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER -} -int h2_getReg () // Get new register -{ - /* Search for the 1st free register */ - h2_regSet_t tmpReg = h2_regSet.intSet; - for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) - { - if (tmpReg % 2 == 0) - { /* Free register found */ - h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("GET", i, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - return i; - } - tmpReg >>= 1; - } - printf ("Register allocation failed\n"); - h2_codeGenerationOK = false; - return -1; -} - -// h2_regSet_t regToBeFreed[32]; - -void h2_freeReg (h2_regSet_t v) // Free a register -{ -#if 1 // TODO : To be rethinked - // Is the register freeable ? - int isOK = (h2_regSetInit.intSet >> v) & 1; - if (0 == isOK) - { - h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ -#ifdef H2_DEBUG_REGISTER - printRegState("FREE", v, h2_regSet.intSet); -#endif // H2_DEBUG_REGISTER - } -#endif -} -#endif /*H2_COMMON*/ -#ifndef H2_AARCH64 -#define H2_AARCH64 - -#define H2SYS /* Has operating system */ - -#ifdef H2SYS -#include -#endif - -typedef uint32_t h2_insn_t; /* Instruction size */ -static h2_insn_t *h2_asm_pc; /* PC for code generation */ -static h2_insn_t *h2_save_asm_pc; -#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} -/* aarch64 / power examples : - https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ - -static inline ticks_t h2_getticks(void) -{ - uint64_t Rt; - asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); - return Rt; -} - -static void h2_iflush(void *addr, void *last) -{ - h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); -#ifdef H2SYS - __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written - long pageSize= getpagesize(); // Make the page executable - void *ptmp= (char *)((long)addr & ~(pageSize - 1)); - if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) - { - perror("iflush: mprotect"); - exit(-1); - } - /* Gcc function to clear data cache after code generation */ - __clear_cache((char *)addr, (char *)last); -#endif -#ifdef H2_DEBUG - printf ("Flush data cache from %p to %p\n", addr, last); - printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); -#endif - if (!h2_codeGenerationOK) - { - fprintf (stderr, "(iflush) Failed code generation\n"); - exit(-5); - } -} - -static h2_insn_t *h2_malloc (size_t size) -{ - return malloc (size); -} - - -#endif /* H2_AARCH64 */ -/* In memory instruction generator */ -#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} - -/* Single instruction binary code generator*/ -#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ - } while(0); -#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xe & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FSUB_RRR_F_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xe & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x2 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x37 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x37 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_64_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x37 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMUL_RRR_F_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x2 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RR_F_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x78810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RI_F_32_1(r0,i0) do /* mv */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_MOVI_RI_F_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x3d & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RR_F_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x79810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FMOV_RI_F_64_1(r0,i0) do /* mv */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x72 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x272 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_ADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FADD_RRI_F_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x6 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x6 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -#define A64_FDIV_RRR_F_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); -h2_sValue_t aarch64_genRET_0(); -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); -h2_sValue_t aarch64_genRET_0() -{ -// No generic optimisation for RET - -// No specific optimisation for RET/aarch64 - -A64_RET__I_64_1(); - -} -h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MUL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ - // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) - if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) - { - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; - } - /* if (isInt0(P2) || isInt0(P1)) */ - /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *0 P2 (generic)\n"); */ - /* #endif */ - /* return immValueZero; */ - /* } */ - /* if (isInt1(P2)) */ - /* { // X * 1 = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P2 (generic)\n"); */ - /* #endif */ - /* P1.dontFree = true; */ - /* return P1; */ - /* } */ - /* if (isInt1(P1)) */ - /* { // 1 * X = X propagate register result */ - /* #ifdef H2_DEBUG_INSN */ - /* printf ("Optim for *1 P1 (generic)\n"); */ - /* #endif */ - /* P2.dontFree = true; */ - /* return P2; */ - /* } */ - -/* -*- c -*- */ -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -if (isInt0(P2)) - { // X * 0 = 0 Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *0 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, immValueZero, P1); - } - -if (isInt1(P2)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P2 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P1, P1); - } - -if (isInt1(P1)) - { // X * 1 = X Avoid 1 operation mul -#ifdef H2_DEBUG_INSN - printf ("Optim for *1 P1 (aarch64)\n"); -#endif - return aarch64_genMV_3(P0, P2, P2); - } - -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSL_3(P0, P1, P2); - } - -// Mv constant value in register, then do division -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI mul (aarch64)\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); - // No return continue instruction selection -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FMUL_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MUL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SR instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SR - -// No specific optimisation for SR/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SR instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SUB instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; -} - -// No specific optimisation for SUB/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FSUB_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SUB instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for W instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for W - -/* -*- c -*- */ - -/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ -/* { */ -/* #ifdef H2_DEBUG_INSN */ -/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ -/* printf ("Store 0 (aarch64)\\n"); */ -/* #endif */ -/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ -/* return P0; */ -/* } */ - -if (isValue(P1)) - { // Store constant (Should use RRI variant) - h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RI W (aarch64)\n"); - #endif - // MV const in tmp register - P1 = aarch64_genMV_3(PTMP, P1, immValueZero); - // No return continue instruction selection - } - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P1; - } - - if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P1; - } - printf ("Warning, W instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for DIV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// if 2 operands are constants do division evaluation -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; -} -// Transform RIR in RRI : P1 & P2 permutation -if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) - { - h2_sValue_t PTMP = P2; - P2 = P1; - P1 = PTMP; - } - -/* -*- c -*- */ -// X * NPowerOf2 = X >> N (immediate shift left) -if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) - { - int shiftValue = h2_log2(P2.valueImm); - #ifdef H2_DEBUG_INSN - printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); - #endif - P2.valueImm = shiftValue; // Instruction shift left immediat - return aarch64_genSR_3(P0, P1, P2); - } -if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) -{ - h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; - #ifdef H2_DEBUG_INSN - printf ("Fallback for no RRI div (aarch64)\\n"); - #endif - P2 = aarch64_genMV_3(PTMP, P2, immValueZero); -} - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FDIV_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, DIV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for ADD instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -/* -*- c -*- */ -// If 2 operands are constants do addition -if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) -{ - return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); -} -if (isInt0 (P2)) - { // P0 = P1 + 0 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); - #endif - P1.dontFree = true; - return P1; - } -if (isInt0 (P1)) - { // P0 = 0 + P2 - #ifdef H2_DEBUG_INSN - printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); - #endif - P2.dontFree = true; - return P2; - } - -// No specific optimisation for ADD/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_ADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_FADD_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - printf ("Warning, ADD instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for SL instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for SL - -// No specific optimisation for SL/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, SL instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for R instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for R - -// No specific optimisation for R/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) - { - A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, R instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} -h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) -{ -#ifdef H2_DEBUG_INSN - printf ("Start code gen for MV instruction\n"); - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); - printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); - printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); -#endif // H2_DEBUG_INSN -// No generic optimisation for MV - -// No specific optimisation for MV/aarch64 - - if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) - P0.regNro = h2_getReg(); - if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) - P1.regNro = h2_getReg(); - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MV_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_FMOV_RR_F_32_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_FMOV_RI_F_32_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_MOVI_RI_F_32_4(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) - { - A64_FMOV_RR_F_64_1(P0.regNro, P1.regNro); - return P0; - } - - if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) - { - A64_FMOV_RI_F_64_1(P0.regNro, P1.valueImm); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - - if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) - { - A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); - return P0; - } - printf ("Warning, MV instruction generation failed\n"); - h2_codeGenerationOK = false; - printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; -} - -/* End Header autogenerated part */ -// -*- c -*- -#include -#include - -/* Pointer on function which take 2 floats and return float */ -typedef float (*pifff)(float, float); - -/* C compilette prototype */ -h2_insn_t * genAddf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genADD_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genMulf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genMUL_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genSubf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genSUB_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -h2_insn_t * genDivf(h2_insn_t * ptr) -{ - /* Code Generation of 3 instructions */ - /* Symbol table :*/ - /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ - h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; - h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; - h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; - h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; - - /* Label table :*/ -/* No label table to avoid C warning for empty table ... */ - h2_asm_pc = (h2_insn_t *) ptr; - h2_codeGenerationOK = true; - h2_codeGenTime = h2_getticks(); - h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); - h2_resetRegisterMasks(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask initialization\n"); - #endif // H2_DEBUG_REGISTER - - r = aarch64_genDIV_3(r, a, b); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - aarch64_genRET_0(); - #ifdef H2_DEBUG_REGISTER - printf("Tmp registers mask reset\n"); - #endif // H2_DEBUG_REGISTER - h2_resetRegisterMasks(); - /* Call back code for loops */ - h2_save_asm_pc = h2_asm_pc; - h2_asm_pc = h2_save_asm_pc; - h2_codeGenTime = h2_getticks() - h2_codeGenTime; - h2_iflush(ptr, h2_asm_pc); - - return (h2_insn_t *)ptr; -} - -int main(int argc, char * argv[]) -{ - h2_insn_t * ptr; - float fin0, fin1, fres; - pifff fPtrf; - int resultOK; - - if (argc < 3) - { - printf("Give 2 values\n"); - exit(-1); - } - resultOK = 0; - fin0 = atof (argv[1]); // Get the users values in1 & in2 (flt) - fin1 = atof (argv[2]); - - ptr = h2_malloc (1024); - fPtrf = (pifff) genAddf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple addition of 2 floating point values:\n"); - printf("%f + %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 + fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genSubf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple subraction of 2 floating point values:\n"); - printf("%f - %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 - fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genMulf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple multiplication of 2 floating point values:\n"); - printf("%f * %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 * fin1)) - resultOK += 1; - - ptr = h2_malloc (1024); - fPtrf = (pifff) genDivf (ptr); - fres = fPtrf(fin0, fin1); - printf ("Simple division of 2 floating point values:\n"); - printf("%f / %f = %f\n", fin0, fin1, fres); - if (fres != (fin0 / fin1)) - resultOK += 1; - - if (resultOK == 0) - return 0; - else - return -1; -} diff --git a/CodeExamples/Multiple-flt.power b/CodeExamples/Multiple-flt.power deleted file mode 100755 index 04c082a1413fd1a7d626f8f33069e7adbadf9924..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78456 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 literal 0 HcmV?d00001 diff --git a/CodeExamples/Loop.riscv.c b/CodeExamples/Loop.riscv.c new file mode 100644 index 0000000..adb1b05 --- /dev/null +++ b/CodeExamples/Loop.riscv.c @@ -0,0 +1,790 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifii)(int, int); + +h2_insn_t * genMul(h2_insn_t * ptr) /* C compilette prototype */ +{ + /* Code Generation of 12 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t increment = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t res = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t k = {H2REGISTER, 'i', 1, 32, 28, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x10000FFF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + res = riscv_genMV_2(res, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + res = riscv_genADD_3(res, res, increment); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, res); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000001]; + i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res, resultOK; + pifii fPtr; + + if (argc < 3) + { + printf("Give 2 increment values\n"); + exit(-1); + } + in0 = atoi (argv[1]); + in1 = atoi (argv[2]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr = (pifii) genMul (ptr); // Generate instructions + res = fPtr(in0, in1); // Call generated code + printf("%d * %d = %d\n", in0, in1, res); + if (res == (in0 * in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/LoopNest.aarch64 b/CodeExamples/LoopNest.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..373339af44e0ca6b6d3538b9b84d2e5f299eaad8 GIT binary patch literal 52232 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 YS3LhCkeR6bj}NI*^e%< +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_I_I_64_1(i0) do /* ba */ { aarch64_G32(((0x5 & 0x3f) << 26)|((i0 & 0x3ffffff) >> 0)); } while(0); +#define A64_CMP_RR_I_64_1(r1,r2) do /* cmp */ { aarch64_G32(((0x758 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((0x1f & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_B_GE_I_I_64_1(i0) do /* bge */ { aarch64_G32(((0x54 & 0xff) << 24)|((i0 & 0x7ffff) << 5)|((0xa & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_CMP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + A64_B_GE_I_I_64_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genLoopNest(h2_insn_t * ptr) /* C compilette prototype */ +{ + /* Code Generation of 64 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 11, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define aarch64_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + 0, /* h2_prologue_00000008 */ + #define h2_prologue_00000008 8 + 0, /* h2_begin_00000009 */ + #define h2_begin_00000009 9 + 0, /* h2_end_00000010 */ + #define h2_end_00000010 10 + 0, /* h2_BA_00000011 */ + #define h2_BA_00000011 11 + 0, /* h2_prologue_00000012 */ + #define h2_prologue_00000012 12 + 0, /* h2_begin_00000013 */ + #define h2_begin_00000013 13 + 0, /* h2_end_00000014 */ + #define h2_end_00000014 14 + 0, /* h2_BA_00000015 */ + #define h2_BA_00000015 15 + 0, /* h2_prologue_00000016 */ + #define h2_prologue_00000016 16 + 0, /* h2_begin_00000017 */ + #define h2_begin_00000017 17 + 0, /* h2_end_00000018 */ + #define h2_end_00000018 18 + 0, /* h2_BA_00000019 */ + #define h2_BA_00000019 19 + 0, /* h2_prologue_00000020 */ + #define h2_prologue_00000020 20 + 0, /* h2_begin_00000021 */ + #define h2_begin_00000021 21 + 0, /* h2_end_00000022 */ + #define h2_end_00000022 22 + 0, /* h2_BA_00000023 */ + #define h2_BA_00000023 23 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0F01, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp = aarch64_genMV_3(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000012); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000013); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(10)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(11)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000008); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000009); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000011); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000010); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000015); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000014); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000020); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genMV_3(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000021); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genCMP_2(i, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_prologue_00000016); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genMV_3(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_begin_00000017); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = aarch64_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(7)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = aarch64_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000019); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000018); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = aarch64_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_BA_00000023); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genLABEL_1(h2_end_00000022); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genADD_3(h2_outputVarName, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000013] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000009] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000011]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000015]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000021] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000017] + 1; + aarch64_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000019]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000023]; + aarch64_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resC, resD; + pifi fPtr; + + in0 = atoi(argv[1]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr = (pifi) genLoopNest(ptr); // Generate instructions + resD = fPtr(in0); // Call generated code + resC = in0*(in0*10+1+in0*11+1+in0*1+1)+in0*7*in0+1, + printf("Result C : %d Result D : %d\n", resC, resD); + printf("Generated insn # %d code generation time :%d\n", h2_insnGenerated, h2_codeGenTime); + if (resD == resC) + return 0; + else + return -1; +} diff --git a/CodeExamples/LoopNest.power b/CodeExamples/LoopNest.power new file mode 100755 index 0000000000000000000000000000000000000000..559ee8eddb71b73c267b94e7bb428a8a7b41c45e GIT binary patch literal 78376 zcmeHw4}4VBmH&M+lgxyKF#J(Ni!un<#0?=JrGtWm5F`=QRIswU?oL87BvX?~Oa?pH zM1o5{jV;|xcCp1SmbgWWyXY@==@whMrY^R$i~EaP+R|sJ0uQ222|xF9AVZ9x(qU52c&XdVrW1~k7o&|8)%`Rl8|5)=P{7< zNK4qU+rTO)q&CJc$?AE>$oIUXNqPkvNg!ND8LDz59+fNOa%Egj!2uRbL8Tw*M)yY6 z4^Y;ppa*$$dE~D_OUdeAhU%%DyNjMAl;!X&;gEqA3KA_{A4fTobG(;i2IAYfzI1ju z%knFz{IIwwuyy&e#ZC3gmzA`)lq{usrQCo-v;NjQ2qpbIMW&1&GVe6pQ*jeMAGi6U z>XZwJ5Ak&3CcBb;Ik?IHxw!Li6OFo&9QQ?KX4H%(r#e#MD}YzAXfAbo8v0df@OP%c z&r5?ZOoP84cn|L6i|m?8{tapHA4-Ftkp{mk4PN-efsknRx3#sjiPr6*cKWGnti?lH zAQ;*vn*Gh~{*Y+!hgxeJ{Oy7J{Gz$FttI5I3yJ31rlyuU(H^Qtd9m$NZGn(q)P`CD z!skPr)%n^(wQV6^b8R3f=$RsJxmdrks(h_)X~~k0fvlmqCCFqxh$w7H|CuqAui?J{ zplSzS>ir^IZxij5iOZ!M{lhg#Q_QKW(1cfUN_lQ!ldLX7nqo^`1tvTr*^2WMiZW5 zQC+Pjyt&O6h&3aXyB>%>Zhx@T#>g)lBfoWweD@gnTQcM;|AupmI?iR!3&SPeUGOpa3@vHI(`AcZ zd{?LLs|L5c$~<|Z7^!Sww0IlM^X{+@?8q_ePR?SpV+Zx?WC0O-;|PtE0O9+-mRrH?N53kG@@c|I0V%`roXsu6}uE>HXii zA#~NtJ4r`ffBA;*LeH|{q7Kq^rRXa2idWt?c>Ll9O%$zIF!$OWLae@UZS^CaWE*7< z;G$G+Nbg#MGOs=Yzm&m7n((ZUc12r5-LFEfS0U@ergjHi67?BC*%AGfx1WYA;oQ|7 z;SUEoex>Dfl#10Wp1MuI_ns9VvAP$XY9-(_?3LeCKSFg=oEde0vLihILDWB`qel2vJawm#vedIIfV-%kLh-w3|OBhI4E@P-AQ;Z18hA4Ok8H19f#?(m2r*s-WM59Lar5BlNCn*fRS zU484yk$396yWTeXF0xM-WLN!Fk`7ur9qwTrTE)(h@chqpg#X|PsYlqPM+fUM7j-wn zZuI=xt)ioe@%O=Yt>W2;l1sc>=Z(H)$OU>y3!S82x}gK$+tb@^ex3DwNE218xWV>@af-ngs=Mn{OUx%qI;iO zP4VgKSRm%EcxpYRr*ssW{9VkxqI!>_@ADww3LFrsu z0RC!(?}1BbixiKlj7?NUH6e(0S7~Jq$6^)WwTN9MZ&mL#@GZp=@uI#5u$RinzLL{( zMNZ*feODR9tcTjqf5+SPKB;#Zbgz0?*Qx!_?<|`@Jf!a<4PTNTu-&fGTS@k!PNVNx z-AnRPyr$Aw(zDJZl}0=CR*u%4>`5-DyLxF zc%Y1A`kwRJ9b~`ohAP=!$QDWcok-W;DO;4Hzw?R%xP7F1l=_kfhKqK11dUyyX1}y~ zRqs6Z1C1}J`vUIhps1qpBTD*0whLw+PSNM3exOk7jAWV0QeTE~cMbWs4E}xMw}yXp zy~g_vr>S1U*F_H^HUc+h7hw@xRP04L$}8-;I*MnEQ`f*&eHb^pyu@z{`2CD|ybXR& zn)s3JCpspmw&8(|a7R|XX~;@8m`LoI$4WKM^n>S7*nL1eJ90vt85tD%$Z0Y6!dcic zB77IV1-r7X%6vX`>?=;lcq@uJM2_s^PV6cNoPv1!&oJ73 zZ$IidD)h*Jm>WF-eFw!E?`z9xo)aB`P8Zyw>Oukcty{80WwPF+tJ0fn@P6uDF-dyY zI7aL3G3gE4zOQ=ko+Q1o_c+SmWhT9C@3Y>=vnMCcTWzED?lS4Ez2ACIlE1^6F}LkP zzyIC;mwKK+<3d03ALV@2$5B7}F4laJcW+*SeHYA;%U2B}P5s3Y=QW+*Lm%@T`j~$~ ze-qxc4tQ=@FYY zH=2+Bl;pCR-$XAJD-lZSw3Y??+0P`6CJNE${W9yk|jDJc@PT%Lrj_a-bOJn>c^KakS zdjCHB>ov_~l%6!EUot(rJ{Wpdo8~T)qUY`phMuYBD&{%b``uoHlhj^Q%~d`~dY4R+ z-fFJm)-iwhkIZwGH-Ba1t1&6voM1e2l>qZnV_G_1ll+HF^6zK)DVBQ1kU#z2!lj=}oyWR@+7|7XC_j|_5As7XuZzmi*F5oy z%ze#+oUdXkU7H?HU-Ql@MqLz>nfizE^fga2uMcYfu!i^JyReVfjeWcx?BngjK3*U8 z@jl1;dl1uKPTG_EOvLCD_F+$M569R((0vhQsIBioTlq_*sZDnQPrN7{Li#I6U++%b zL+dJ|_C3Bf(1r5dSc~>xExHeK^<~&QJ1f`3TUWLshWuwU$Iv>?S9+(5A<~!D)?b7S ze+d~#pX9amGiQvtNLE^_V$Uz_8kT6(8kW*(4Xg09hNZMx!%|wUVc|FIAx?Zx_~Y#N zLHPYN{C*aGkHGK4@cRh%Z-ut{f=lyV_z>27$s(7S23w)$b>F#`VyZEh5L zM%`Na{nsP8qEhKgypyi1vP0c_v_??Uh{&A@vLc&mPf+FA16_m!Am&^`f; zsZ=l3MRZfZ*Sweh<~f7TrLFFzeo5_-{|aT)`uP_~t37g6C+(3dz5_^;-KdTuQkL|4 zk+m2Hr1!mrattJ+2S9-jn3-LhO$v$GKW}lE2kEk@w5rU6Z7DDfY*d-e=J_QNKod z)4mbuO=Hvv;FaFA|Ec=5ex%iSK;szA!AHIO0RFk!oQQ$o@u`Rp31 zw$fX*XVUwBTYFafWqnwG{PIVc*B{SwzKZd5>kqOUtv{0A$C=;ltzcfN4@}4FBJ)aq zA7_5I_v?Q($j>x$o85Tsikoez*51^P)a+taTC5sC5yg)w)RGXuTjdcq*U}jdqNDRPWvFMo=at^;di%1U zU7Gdwx71me%E?`C4*9LyZ=Kj!>PvEHs?UR{WRvEqtoR9sP7#g)QO#(MiwyfdEu zQzHgWjB#En`jhyY@tA2X_&w;V)`HI=t=59yLYmfmzxVS}+W6OkXv^b1FXhFWC|Pf{ zCL+Dnn&|z~yJC{`F2kBAS#PyAAidRGVmx}MoFnrb>WAQ!ZtYL=t8{Ds(n)$JRhi<< zzz0e1C6lCgwdu?Ntre(!oAp*}!SVQ;d^&1P^gEu1+&xKgp6Wa#%^lTw$oD(Wmrs(v zQ=NzWAnEK(lYZG0kUB}VB{{QjPmpuYKc@q_1m@WZ7zE0OF6&+pL>>a0X5`pnMnX6`fp zg!3;&pZVf|QP-vDGe5(;sQr8p`?=reJ9FdT!cOix^M3R_%5NU@p~>%_AH{e$o_EhX zn9ls}IRbv_-NlgU9nB!{s?Os`za@QLR7`!JdPj2@>6GiwalWG&6vn?_oa}csG(V%c zfcafJ_1%|x@1EXEB=;@j`S)nm6PS+=!Vlwp*RJMgHRx-mekOZ=Uv`PI)9eMyhp&BWL0z@N;((w62>~}!wPUNM(IcIn@C35 z2c-8+Bsb|w?~hfT^!`}!?MIs0AkonKV~UwkdnNmfITyudy0&^F%DtC9=`47<@J_`I zdy%a?8O{?GVoylvISg5qp42BPJ?TBF(v$Xlm7X+@COyfPbp9u$o;)|pr04bEk$V1I z)cMo|){GO;yA3HXYHXco z98;{0YOfr}6yxdIYo<6ZnWQ*w#GFFuO>-z}zqFpBIh4|S5O~#oX%3~@FU_G;KSgt> zlYi5|=)oFJ-%QyvP@{Z*)2O-x=tCuYx~_mw7Jn!rvQmtG+WGuVUu49K4o-7mWwW z@5gsBFS6lSa|xnRa|ueTxrD;gT!PXb{~27wo%jF8+3bXGI^+3l3pi4jA)=hw02M%?CVyG#9WNbiIV9`2&?Z%;k7WTev*(W%(K|54xBgT1|H7;_}^GKE&n2T)u;t6OJ7_av z<`AAK_6`FI%+o=~f8)!Tr}x?BMnMzpw?RhjK*Xgzi@E5T2%T|%=m+|SBGgOrsWUTW zsP8g~^Q<_=bsuMVlHngXQi=K=1g_7y(~CYSfme^9e?PJs|9)gNuX#}_1HIvwekb;Gox1n6 z8wLJW&D;xv_`5dLub@wn>zE>0C;AZ9?JUCx!(rAH`BK**))jP8*K>f>RzcreO*S^! zlJPk75{E~JpMhbYa#3E2Bi3( zWjEr#0M8Wva{$Q?pzj^VI?HTJvmX{9pZwsqABYs#pN)9zXCj4m!w--BP~R{ca!{XL z%=Io~xRPN7%2S_@d?`mM%K+Mk8+`-qH91Ze zrqL%=oa}fyv7L-SSHHx0R@AdjO$A=7_A*L57DJ z9$_7jFLmr=9YH5`JjA+zE+KCALs!s54@2MNxcM>mky6Q=DsI*!$?Ss6i-040W*S?P z>wF&nR&~5}zVMXM_Kva*1{j`TILJ0ZzO>0Pwh8E@O^yRnT!OyWondS_iF}I7qln7^ z#N`RZ)CZGSS}o`y~BNjQvg(d97o8D@RnV0}hdpNoK`uLE?X&oJ~Efj%f7 zbve@a(G%&@K92V)sq{$|n~xn%Y)=J<&0dManu2wj#c&S81*{|TrO(_BV>|?%^jQHQ z#SZ9uT^VA>gM5meJja2^EXT8vIgT@t1&(;1ru|6Ykd-8#8}hyWcSdX%vOJ{>y$s91 zmu!rDDPJ+m2RbR=GR|KKNIocZ%#D^hd{LB-mSyn4MEbNBj;HoPs+gK5^@-1eJsY}$ZDhEa;a#i)@}-WItRv{8j@7Ii=o0$03g`-&=w|4f+`nl5m|Eskant;_iE&d1 zng0;DiS}u)zcl_jFFX-%do_;uJgt>&5@ws!uubaOCXH;9CP0cy(D#;Rh|3W2DK2Xe zmyL+aR>Wo4Va(Is!Mo;rAP3FUI=J554EHeHi}DnI$d|t9VmUx3ebdePJ%D7d4)|m@ z{DJb(y_YEdZb>sfrHa2t4;lLGWBL0S9%9(f@*-dAv!C?=oz&+b=N|?nefB}0KInt; z(f$njOr%evvkBwv(_Z{qVr+U5o8OT*>;th*#~2=Gc#?HMzSQw3>j*lj;{YJV4(NLe zGsMmb>NkzoHX@mi~dF5up~*oQpk5DaB7}5Xo~H#EMEkCDW(PiX`Xh9 z6=7A?D(5q|!U;(QEahH2R>-sI_|M zV~H`f1wIQ%9QNR{jIrO%uz;b5bws|@F)zy)CqXB5oCQcR1^V8~3^6qa`4m&GtOF5u z*0Yg;^ z@|H?Dc6vdVFs3ZXni~a8bXnGD8$bEY)G?FF#)tm&67`HA7N0$_j4Y> zS}0Xtk*dzez8Y_LWm)ktrJ8NBg>6#CHmP8nRI*Jr0+J6w-`kVHhnta4J}iR|E8)Xx z_;3sR@QH8f8?J;L=5H{_2Lmde~nVu(#UGa_r@L z_cJ`m@G#1gZ;&tL*vE2!PRh{-=tTY@K(g0f_+&r)f%4JA8Tz-0^w(90t5oeERe$|R zU%Vako7%wu>vIBfl0N-_H2xf6eU9Rp#-C%He;knX>4!c?p%2POPh`+%B6ENp&!pBT zRh+zVATc(>)c;AGXT?d@=@i2uhUZuZID6$P7AYaONp5+6bl|h+sKjCYo6Y;k3}-Q%!#W~g>gdWg#>_lCQ=GX0 z$p@hC?attX0_2kq9N7mVdD+iKW@Vp=%*l@X;IZTSh9@3Ll&=T!Jp`PZhk3H&<3TCQ z=LKJ~u?LXa!2*`A5YHrEG3PG>JS=c_DSK|TFxwYJ`KUL84>Gmu!|0=rV0=4i5WvOA<$gmYW z$^OWfvfah9flkU+4@k0sKI2||6Y@#6Es(7SvNb}s)@)-=Mf>n08unyj?^Edg8un;e zh7N|i8SViuk_q`zrZCF{Iw?~ZAjt&!jC;J@$S0XXkf{SQ?S@QyO!j&mYamw&U#fWR zF~w^i%XSDnNwyw9ir2j?+de!~yzU1i*+8FhpYI^@NwyxywhyxPLAFC|uPFAw3liF* zVXwn1!x4tZ7#;^Nk_q`zrhb+QbW*0HfFu*>GwvS^AfIG944IBVrel!lxXE7M#ag{E zg}um^Cs>w2hNl^x1y7O<`BJu%EF0*gY^MN8Hqd9>Ll{Cn$#w#=4MMilknJqn>ly6H zdsEo!9LsQ?;TsGuf)~kzd?{0eWdfa)X&8`X0)57{=?L;krgM<#JY;$UGF>#;tM^%b z!d_hGZk)ZQZ`yV7`|57&XV7=GaNbtdk@e@snGm9_!TBNKsPV4Y zhuFlqZQPL^KPNo`9j$ohy%qZ)fH*(47Viy<6TZtwG+~qnk6lwl(UtU#8~QdC{S8LK zc0;% z-Y;cb2N{iT+zsHI-y?hCXJ7ccOuNW;hA+q#3-Rr|3i(aEv!HKg`Y_}JU-|8*Je>Wb zw&23w_oUb%AN7s#_g<(D^LPJF>$Pv6)pxxe{)2CK&^Ho|?ey5>XCPM(l-;IhF^Dm-iWvDSLr)T@jWN<@d&=9m?ORt4gZ^eXZYWD z?+m~C)t%<=CF;8VG5R)PHGfAE^}mYxUsc~oq`x6!`bHwe6aJD6+e-v<~n>o=4^Cn`()&GKH*58%9Daq)S` z3>x{})KbW9`dc?O1AnHWs1U?2OB^VF+}4O#q;FB?MyhK*-#P1#YC2Epc{r=|`RD_~ zB24^U;_j#i-_$&*>l;qsK8||;_c7c@aUa3mkNYt0L%0v(?!&zwx7mN>i$|f?n}`pH zP=j*r3+s*lrA#q- z#wU)5(ckikamgQ}FJHfIJOyI(Ybq)xL|?vUJmhitH*K64{n}fq$5S9C|E4?2Cq#ee zc&PFHc7OZ!rjTbXVt8Ra!dO04$S3K~^+w3~>xo^^GoPrEV$l-{H2Xc*FRZ5m+K25o zoCc)tf;W9m*Ij7trvVEA_kUj3Hv)#gpzE!G6@RYlJ%D=w`vJTELe~cYi+gl^7;q1u z8_lgBqkSo$<1cl+nwlTJf*1lkjE|-613dYdt{($D{xw}c3pj)h!C@C-Ut%h`#D{20v!1s>ILloXI(!6c=1QNej2dwg05c#9DEBSghPlP^yr%b3ok+*RO`k~ zmv-On!VzAheK=1O_|7Q40WCx+Xd5ZBJZFt4&t5Z!aJcV!5Oqp?e)R!u&D6P@PzaX? zcQx)q$UhD!Zp!b{rmwkQ($vLiLddFw{f4O2P5C`B8e2dTQ9b)`i#@u2l3+!CndD() z3(7x=`!MpUKIE6m{F{wBD4+Z_g#0%s|EByhB}NNKD1QWZKYVtO@+(*mU%Y$)WLpLw z)=+*q*Iyma$DvaZLjD3nhib+D)69Ph@L~9VGnF^hzaIG>pu)&MjQorA;c~ML>`!Y{ z3(@Qc-2FveKa2rBk>*O9q8R{9-T}k62{g91h(z)^hlJ~^x;{dPoAL+Z_HK>QxG2Uj z$P`SKH2pCeyVp)cWV2$>3_i^^Q9ij0@Yr@f%r z|Bt#JL7XPi6vu3H6f`yer0Yiw8k4-97|jr9-uOP+r(wUi-uA3mT>@=m&LBqkg|e=} zY08oIRXL=Y2WV<<3*JPm;2HAt#cX5yW2ro~32KXnev7t;v{;As^4D4W9cv%4f5o=; zfVMuL;-flWtj}I^=H-`${>^B29VoNxztJC18SAnvU|GPjfMo&80+t0V3s@GgEMQr{ zvVdg)%L0}KEDKl`uqU|GPj zfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg)%L0}KEDKl`uqU|GPjfMo&80+t0V3s@GgEMQr{vVdg) z%L0}KEDKl`uqaTz82R+cY`XAWbV)Bi>W=3xNURXK3=0@u#!vx# zc9}1mERWAb%ZtA0P1h^~2q(iU7*=K(_2IFVP#al(@RQF>7Asf4^z`{@x=IZoau_Q4 z-qj6#M_51DQ|hnmILyyK;e0MWd0?kumvj{jvfkl_*IdZNND8iXojitSIY9M(F~1z)s9IHx>P$> z?Z&{ye+_wSW984@XUIDkCrL;d^}U5=Zqzr#{f3*Vj&b~{=Y+y|xE43tM>e4@w$E{f zL{Fc4-;7)9dI5SnWSe(s?V!(FhW1R^TXEYo*UeyMvpF9l;Bc0M!sc?WBA{i{7w_$V zjI?&m6;~3uE$b-&`&aR!70y{e>32b+70tREX@?^#5DW?X{gi#}<$nNRb7d_?`79S| z+C<#wgY>o!&Gb>xKS7SYU}hPmAETeyvo;avqMr}VY9la=AIH2IUkAv}bNt+qqa)?4 z1uMspBmW=qAe^6~r{<TmDv|W-ev*(!2}!C?bJ4H+IYMqF zo>zwVzB@+!!Y{|kwvU-x-Jeu*gmTO#S#twGu85v20-kecSAU-#uQNuG4ilgURY zSuB%Zr{u?E^81u5m&qYY-XfD^WcL=CByHVwGI@xSL7DsxC3nc=zfy9yO#TNY|3W4& zQu50(IUT?5$M9qSA&}0iWW?ufLv0S{To<`*Y8Pe9o7Rss$Xo!6vcl&$Fh( z(6d$(a%hT7--fczmvZM3zL4-Q=Pp57;@%8}1bkwXq7x5;O_$lFU& zI#0VOLZ(h3u4i)oT?&yyokEi$b)w6#9S8Ac9#?t(L85*e`L2q5YO`W$5Jg?wpzk;kJppW%*Czmo75AWP!BS^$@TQLCx5u*-?95 zgtL=-_TPYndpP?LXlyTDu?`#@%kaa!XqHj6>SBz(CA$d(bUTI1)dnd0i76YAnnHb( z{6QAY_*|~P!Y_B9xj!KF7EP-KD)%=KOCHfJR zq)Xes2g2u{lDU^t%}B{B|22u5PlBw)y$W|e`CF?fCEP=}{{r{4pAp@i?lPo*iTf4Y z?ot+jEI`-&sAPITXj`TcW*(mA;+}CAlg-pN*}foVYMX6)@Oy{t^B|g~c#weNvIuIS zTk}q3*L@8k=F+H9mw~{MWpe*p?KR}vMFhX8YG`d~ z4}=$Q4TRbS>Qm6)w2dBB_1lA>!Na|an*zb@aq>XWA6kr?pqXBY8*B}sw+roP^|zNa zlBDgSddw6T;SK_UmduFlaSW+9Q?5KsOP(&!QbR2VJ1c57f!uqEU# zsUsVNny3<5M9;@<7c@qV(imj}A%k9oBpHnuqsUCUD_t0p>Fe4;fw<+>vcdjO=#}Tq zBimm+&!)lhaEn?)*nc834Kxg47tN{aUEIB;_k`xMRQfN5wDw2Sv<`(WJmY6)d8(qMLFbhVJOFOFd|IdrjVN(t5vHMcHq zZ>w9}00-19T3T}5b>?JU`*wj9tY^(853-h*EQy7yFVNm%dI;9GwF;k)0{ptAzL01S z1eg1^HMM*y5Zq>>+a6@1CCiDZv865KK@k(9*052wy{@Iz?+es}KGfLeudVmB`5OZ5 zA%7d?`?l3K2by+>bxqrrFZ12m(pE2mjrB5Xxvv#mQH&(mE}B|`4W9az?OU7t@mhlI z23}@T{W2kcwg=k-4MBgs6blM1_fg|qvYh4i8oEiO2-Y_HrFqsaS;A|4&!T2D*Hr<( z-%sp}ih&HaP#iC+4TahQTepY&KvDi8gJ98;rC!gX2G63~mU*0Mc_{-yy{hZ>0rV3EJAE!ctwR1CtpyBD># zp$n-CwX^|=K4ejIOTE8o6*ZzjZPOxu*k32wYuT<)GG>Rm##+PV_xameM9@b{x8E1H zCCm(Ly}!MVu!dm_?;9?XX|f@)udfZ&vfE=7B>2C+N%+cJTAI*-NmgWT?jU{smLO`P zZZ?h!Fa4;DhnUZe@Iz_BP-&%8yi6@c2Rrt|7e%?z`!uDR}-1M0Dc(VA%CR1DZ-WfhT4l#Z%{$&=q7sENW!-uF{;gClA7 zos-L}!R|blSHs-NH05Jbr%2c_CGe`1wJ9Itwur5`6Y%!fdkhmAW4I&sJ|hvI6?>17 zh|i9_??}WuMXL7zcI=g^_XmmeIYPaMNW@POruP}KEIZzwbg|uHNF=b$L921KZjNQy z#njmTZwx8v^F^xn1a>h^xVuvEaf|aQ@zaIp9W6z@Gel`h{7g}n5%`HQU0{)w;~1TOwfb^spv09ek%OJH26~Bu?QUH-y0=z}@gQk6apv0|= zFU?7et6IkQCE-5>ye8s)B>n07Gu(vlVgDL$AB3QNH>$UFN+SPsdVN{)nJx;G;_zz{ z?-t?RiG04n{0Df`2aodlXZ)tJ=MeBD=YEzGD?NGrn(=)}@?QkrhW6XR^3$4vE(a7R zy}G9w@|-l#Vm9M9=Nou64A6@Ts`o?^{}qfMOu|+>0#HTN* zKU~T9nj}2Ej3Ih&()bf%{6G@@mnD95yZAe%FH55T7sl5l$@v?`dy?o2uxUW@oK3>7 z0$vlN`_G%0zAK47An~K+?2!1;{XFgIYxJfq>HYFUl795K^AEt!AUh{*+J2AlHF;tm zsvu1c(hsf|CEiGze_u(1|1}zpCq+L`d&R_m<3|ntBQg#kJLspI8FP9j@NV!)9v40Y zJn^acn89a=4=M~0|E;6P%|b~(x&m(+{LRci!tMGv7v048p@oU^Z)N=9T$YFRYL)oW z^?o4@{s8lFtvC1_#WP(`0ZzBg5ZI~c1@oz9J_orUeuMFU z1U%`xkNL10MUd&;vyFNWvpqk}_){M-@C8#1MxO(o7HCxi>iSx@0d1_RKY2VbenonGdW4YZP+P-ZYmgPR*+ReA!?%P+F`=_Pg5&+2(KekH*%vH~U&8 z^Y+?%{l55PgFl1~45MgZThsRTMq<*8ji{D7^Ik-$yq2seX>AJm>X2R1+J^0&ZDnQa zH&&Ie^(`$~@-Z=*2<%&H8~n7!AA`~#4ur-aY37ZtG01o?L2j);lR$6``euJKOqM|8 zgYyHyyM5IgH^ZJSP51g!=+?SDL_26n1(UWcMwwm@hsgBd;=gHtOu z3tN&ztoXxQ*W6OIHibsDp_V`b!-O3eW3S5R!>+M!U8T>6?aGSVMakyd)|N24rCZ|> z0xLGR1dTl|*&JefJaRh=akj0^??(g+>3mZlvDjt|y+86b_=DwZeAucEq1m>XL(k`z z8<4UU5!t4VzUze4$Hat9X2QrIzTJPXh!refzYY~JzF`ykl-TZ+DWXg)IDAZ)7_Uut zltT*cZ;W05qNyeyuk%h&nOlm97kVOWtnxmgY~Br<{Glq^BSThui?6XZSdR_xqBF%fV1girP*sGb~w8o0Be-Y3u!ylq2V%-bPmtl*l83aQ)H_I8$znwsFy zHB}uev5CsZRETq0drLKB@cB01vX;9_?pn-DxUHE`vEIOhi`8}ey3M{)AxheJG>2-p z0*2ZQ*r-zIyzoL&l*rd_Ys#w@(S~pdcI8VNYtado)b9wQumMADM$WzdwszPg;lYPI zZ2#6$0ZyTd6eZHkB_V$pX&LS%Z7niHOZ<(9dm1umuQ~Q4O5~t`3TbSR^F<2!1=dsZ@@lsZ4e!-dXz6^RMyt5Z3u0Cq8AM+4I`)|_47=@oYWxu z-XZOj(9}dOa{$#o9iY6D=jv*nWaJvJKb?3`<<)*3pu9W=i2d?3CHDMLq%ft3l~?DN z0p(R~07*khwV$B)ECKGfINPi0AK-mPKzXShAF6{cRo-|K@?|*AL&WMo%jE&(MeAm| zXgWqoRbK5>tpyHK?0hx4GS;?>VB?0B7cA%8}icY~TprW(S z>RIhy(tMsSkNh1iKchth5=5%Xt9?#Dd7)*>OVyvO|2@d1^5q6uY(EtHqVn>x!t_YH zgvsSU4IGj1bT_tdiv3f0seKmXDXx!t-i3s@yin_F3QAmk+YP9GJu1QQvw-IEYM&fX zUd2qO0Gm}k%JcG6UfECW*8n>*V=jN5 z%LB@*C#nAA@=tPkMW*(NJ?|Lh)jH64iu+GJ(|V2SSLM}ya_KnBe;Z}V)vCPOcP``d z1H>GciVtN!CD(D}nd^`3PxDT!ieJfuewd%)b1zVoR`tV^l65JU4^tV_rOGMz1LT?O zSL^C9SES@rEL1u5{C|-!*RR%X-CVv}5i(3Je+qc2KUq&zenwJxR-d^G@e-F$A`^W~ z;ZX&cAX%UDY03}ClSOo_H<5D^J28@`{E*9_d`2}aW|Le#8;E2akv^1bU>o9&l^l|3 z=@d5MlI?df-=Hj19iJ>6uS@Z{lFM^;3@n&sP^?pgN#zw`VVd%-ml*}S6d}W8`x8}? zi6rGPmoLB;E?x6*e;l`pA2oi_zoSVq5ip>;+Ni%!H9U!p>(7tan@C;0loZ27M`+Dg H(xdqQm5t+d literal 0 HcmV?d00001 diff --git a/CodeExamples/LoopNest.power.c b/CodeExamples/LoopNest.power.c new file mode 100644 index 0000000..73da90f --- /dev/null +++ b/CodeExamples/LoopNest.power.c @@ -0,0 +1,1257 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_BGE_I_I_32_1(i0) do /* bge */ { power_G32(((0x4080 & 0xffff) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_CMPW_RR_I_32_1(r0,r1) do /* cmp */ { power_G32(((0x3e0 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPWI_RI_I_32_1(r0,i1) do /* cmp */ { power_G32(((0x160 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_CMPD_RR_I_64_1(r0,r1) do /* cmp */ { power_G32(((0x3e1 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((r1 & 0x1f) << 11)|((0x0 & 0x7ff) >> 0)); } while(0); +#define P1_CMPDI_RI_I_64_1(r0,i1) do /* cmp */ { power_G32(((0x161 & 0x7ff) << 21)|((r0 & 0x1f) << 16)|((i1 & 0xffff) >> 0)); } while(0); +#define P1_BL_I_I_32_1(i0) do /* ba */ { power_G32(((0x12 & 0x3f) << 26)|((i0 & 0xffffff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genBGE_1(h2_sValue_t P0); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genBA_1(h2_sValue_t P0); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genBGE_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BGE_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genBA_1(h2_sValue_t P0) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2VALUE) + { + P1_BL_I_I_32_1(P0.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genCMP_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for CMP instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for CMP + +// No specific optimisation for CMP/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPW_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPWI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_CMPD_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_CMPDI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, CMP instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genLoopNest(h2_insn_t * ptr) /* C compilette prototype */ +{ + /* Code Generation of 64 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 15, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 16, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define power_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + 0, /* h2_prologue_00000008 */ + #define h2_prologue_00000008 8 + 0, /* h2_begin_00000009 */ + #define h2_begin_00000009 9 + 0, /* h2_end_00000010 */ + #define h2_end_00000010 10 + 0, /* h2_BA_00000011 */ + #define h2_BA_00000011 11 + 0, /* h2_prologue_00000012 */ + #define h2_prologue_00000012 12 + 0, /* h2_begin_00000013 */ + #define h2_begin_00000013 13 + 0, /* h2_end_00000014 */ + #define h2_end_00000014 14 + 0, /* h2_BA_00000015 */ + #define h2_BA_00000015 15 + 0, /* h2_prologue_00000016 */ + #define h2_prologue_00000016 16 + 0, /* h2_begin_00000017 */ + #define h2_begin_00000017 17 + 0, /* h2_end_00000018 */ + #define h2_end_00000018 18 + 0, /* h2_BA_00000019 */ + #define h2_BA_00000019 19 + 0, /* h2_prologue_00000020 */ + #define h2_prologue_00000020 20 + 0, /* h2_begin_00000021 */ + #define h2_begin_00000021 21 + 0, /* h2_end_00000022 */ + #define h2_end_00000022 22 + 0, /* h2_BA_00000023 */ + #define h2_BA_00000023 23 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x1F80F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + tmp = power_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000012); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000013); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(10)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(11)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000008); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000009); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000011); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000010); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000015); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000014); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000020); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000021); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genCMP_2(i, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_prologue_00000016); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_begin_00000017); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genCMP_2(j, len); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = power_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(7)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = power_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000019); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000018); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = power_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_BA_00000023); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genLABEL_1(h2_end_00000022); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genADD_3(h2_outputVarName, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000013] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000001] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000005] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000009] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000011]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000015]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000021] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_begin_00000017] + 1; + power_genBGE_1(intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000019]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc))); + h2_asm_pc = labelAddresses [h2_BA_00000023]; + power_genBA_1(intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc))); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resC, resD; + pifi fPtr; + + in0 = atoi(argv[1]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr = (pifi) genLoopNest(ptr); // Generate instructions + resD = fPtr(in0); // Call generated code + resC = in0*(in0*10+1+in0*11+1+in0*1+1)+in0*7*in0+1, + printf("Result C : %d Result D : %d\n", resC, resD); + printf("Generated insn # %d code generation time :%d\n", h2_insnGenerated, h2_codeGenTime); + if (resD == resC) + return 0; + else + return -1; +} diff --git a/CodeExamples/LoopNest.riscv b/CodeExamples/LoopNest.riscv new file mode 100755 index 0000000000000000000000000000000000000000..a782ca2fd27bb2e325c12f423dd4b1d88d45da55 GIT binary patch literal 49712 zcmeI5dtemR^~Yy3n{0RpXteld&0|^95MGw5RSaPvpa>N3S#1bOfY^}4Bv7regjyTv&@SV=@i|S4qQ7JOJ!MdqRPF?Bc} zN8cKUDpO&rrpUacKSECQ_n}|P0ca`GZ_jZh{41H86gTZs?7oQ~7iSeLVUkN6s(eJB z6ubZX^h18-5d93VO`<=1en)7NBJvEY4b07%HZV79KyFUn?70I9bBZ$O3>`8cC%0he zkgVjQ{N%wFujmr~wDC9aYuZ6{$RQZ_qI9RYC}&XQ=t&Wr1cPpr9uzr5kIYZxY#mg! zXsb>7rCoGs&eXvXDGQz{kxtF∓)cy88TN)jfkY&Oc+@#})lA`pyGI&waLJ$Hs5} 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_BGE_RRI_I_32_1(r1,r2,i1) do /* BGE */ { riscv_G32((((i1 >> 12) & 0x1) << 31)|(((i1 >> 5) & 0x3f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|(((i1 >> 1) & 0xf) << 8)|(((i1 >> 11) & 0x1) << 7)|((0x63 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_JAL_RI_I_32_1(r3,i1) do /* BA */ { riscv_G32((((i1 >> 20) & 0x1) << 31)|(((i1 >> 1) & 0x3ff) << 21)|(((i1 >> 11) & 0x1) << 20)|(((i1 >> 12) & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x6f & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBGE_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BGE instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BGE + +// No specific optimisation for BGE/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_BGE_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, BGE instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genBA_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for BA instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for BA + +// No specific optimisation for BA/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_JAL_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, BA instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genLoopNest(h2_insn_t * ptr) /* C compilette prototype */ +{ + /* Code Generation of 58 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t len = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t i = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t j = {H2REGISTER, 'i', 1, 32, 6, true}; + h2_sValue_t tmp = {H2REGISTER, 'i', 1, 32, 7, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0001 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0002 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0003 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0004 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0005 = {H2REGISTER, 'i', 1, 32, -1, false}; + h2_sValue_t tmp0006 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +#define riscv_genLABEL_1(LABEL_ID) labelAddresses[LABEL_ID] = h2_asm_pc; +h2_insn_t * labelAddresses []={ + 0, /* h2_prologue_00000000 */ + #define h2_prologue_00000000 0 + 0, /* h2_begin_00000001 */ + #define h2_begin_00000001 1 + 0, /* h2_end_00000002 */ + #define h2_end_00000002 2 + 0, /* h2_BA_00000003 */ + #define h2_BA_00000003 3 + 0, /* h2_prologue_00000004 */ + #define h2_prologue_00000004 4 + 0, /* h2_begin_00000005 */ + #define h2_begin_00000005 5 + 0, /* h2_end_00000006 */ + #define h2_end_00000006 6 + 0, /* h2_BA_00000007 */ + #define h2_BA_00000007 7 + 0, /* h2_prologue_00000008 */ + #define h2_prologue_00000008 8 + 0, /* h2_begin_00000009 */ + #define h2_begin_00000009 9 + 0, /* h2_end_00000010 */ + #define h2_end_00000010 10 + 0, /* h2_BA_00000011 */ + #define h2_BA_00000011 11 + 0, /* h2_prologue_00000012 */ + #define h2_prologue_00000012 12 + 0, /* h2_begin_00000013 */ + #define h2_begin_00000013 13 + 0, /* h2_end_00000014 */ + #define h2_end_00000014 14 + 0, /* h2_BA_00000015 */ + #define h2_BA_00000015 15 + 0, /* h2_prologue_00000016 */ + #define h2_prologue_00000016 16 + 0, /* h2_begin_00000017 */ + #define h2_begin_00000017 17 + 0, /* h2_end_00000018 */ + #define h2_end_00000018 18 + 0, /* h2_BA_00000019 */ + #define h2_BA_00000019 19 + 0, /* h2_prologue_00000020 */ + #define h2_prologue_00000020 20 + 0, /* h2_begin_00000021 */ + #define h2_begin_00000021 21 + 0, /* h2_end_00000022 */ + #define h2_end_00000022 22 + 0, /* h2_BA_00000023 */ + #define h2_BA_00000023 23 + }; + + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x7FF, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + tmp = riscv_genMV_2(tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000012); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000013); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000000); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000001); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(10)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000003); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000002); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000004); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000005); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(11)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000007); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000006); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000008); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000009); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000011); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000010); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000015); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000014); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000020); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genMV_2(i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000021); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_prologue_00000016); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genMV_2(j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(0)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_begin_00000017); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + tmp = riscv_genADD_3(tmp, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(7)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + j = riscv_genADD_3(j, j, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000019); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000018); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + i = riscv_genADD_3(i, i, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_BA_00000023); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc)*4)); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genLABEL_1(h2_end_00000022); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genADD_3(h2_outputVarName, tmp, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)(1)}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = labelAddresses [h2_begin_00000013]; + i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000014] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000001]; + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000002] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000003]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000001] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000005]; + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000006] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000007]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000005] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000009]; + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000010] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000011]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000009] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000015]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000013] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000021]; + i = riscv_genBGE_3(i, len, intsValue((labelAddresses [h2_end_00000022] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_begin_00000017]; + j = riscv_genBGE_3(j, len, intsValue((labelAddresses [h2_end_00000018] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000019]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000017] - h2_asm_pc)*4)); + h2_asm_pc = labelAddresses [h2_BA_00000023]; + intReg32sValue(0) = riscv_genBA_2(intReg32sValue(0), intsValue((labelAddresses [h2_begin_00000021] - h2_asm_pc)*4)); + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, resC, resD; + pifi fPtr; + + in0 = atoi(argv[1]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + fPtr = (pifi) genLoopNest(ptr); // Generate instructions + resD = fPtr(in0); // Call generated code + resC = in0*(in0*10+1+in0*11+1+in0*1+1)+in0*7*in0+1, + printf("Result C : %d Result D : %d\n", resC, resD); + printf("Generated insn # %d code generation time :%d\n", h2_insnGenerated, h2_codeGenTime); + if (resD == resC) + return 0; + else + return -1; +} diff --git a/CodeExamples/Mult-With-Specialization.aarch64 b/CodeExamples/Mult-With-Specialization.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..0e59760f19f933831209c0fcb9084bb23b5f794a GIT binary patch literal 43968 zcmeHwdtg-6x$oMu=au(U-og%#f@l&zR1iE&5)e6}VuFgNz0ORMNisE=2{RJ}p=I#V zdX!pn!N;wy;G-4voO0TFY+8E_N_%XjEiKUFZG8-=r{3E3P*H0tIQRFh$7IhVFG6zv z=}z`uYklkczV)qdee1pUo~8dB;o>0iMEG$Yl(0oCi@DfLHiOv# zvEp{|7;=SAxt~bZ%5_RS9WK!=vIxK;i;H`dJ6V94a+QSS+GLz?Trwow@3n}aav9H! zc#^E|wTbxm+N!umxjUpBC#0+BC`fdlNV-oXopNJRFy*TJQQqiYEBURpxDcYSiyUU~ zXP-;Bbgg+e(n$VT0}sM=agTCO2{2QxqPrG!B>AwRh&L2*w|V^mMqx6$i`mN6tEy|<3o7Pc0<`9~U_hd| zA&$lLmmHGj4ZG18H65y6JkWVRir&IPJTs_|L6JWV70ztOD&JJumCbSzsSgX_WLxTT zn&2vJiYqk1$==m9!30-zo#G4=+}s|{F~NB~kc{S;;AZ(3nc%AJA`+JgPW4k=SD4^b z|J1d{1gAQwu5~6j)pd1wOmK7EchA(1p5FZ8p3^$(yos@0r#J6^x<_~aM$w%>+&;z* z6@9j{xA6F~PQx*RW(to( z_;FKs62dQ;!c!4GZVFFF*rN5N|2c%Go5FJut~P}$5Uw|c7a)9_2&;Ve=aRn8Wzk|%_8!w+y~k&;&i{h`V70$ytmgyf?D~Kmz2^fRVI5%|Vcog?11rK-gsli$Cv5*< ze?0!cLEK%?FFUca*TvZP4#eZ*N&iZ}h&#bzTIX)KWpI}<_I?k#wKC9@wYz$~pgEyy zdl|}w=u+{4_v-XhTMt*|Zo8-KRMpP?z@HA<>WHhip3_XUU&RVocYGS_Mx7~*O>=dleip?L zjupVaMJu6r@=s%Iy%vwJB^=OolFTYi!ap_{c#{PlDl*5j5ItbvdF?Ts&5h}nxhEkH zPY2B>@$^6^J+^2q>Ue37Gg?b{2I;j&@7xMpkvAdp>CHdld4x>8$Huen<0VK_kJiR! z!!2=j$7TRl;6j|MoAZe2odHU3HsUH-_Y9H2ijnnF?07KcW-%oi0?J>~q2d%cH?4dHymVuUm7U^A?klnC$ zu0gt_Q!aBo;x)oHj^#k74%Yp)&bqtErlXe5V+F2m zjhVtZ2wP2I2f|KMSVuUQbrXN^<+ek-EG|o@;>oP8JuWNTLpWyJ;_<*kOWRF$7KfdU zhknd9v>Rok@HE1M%}s~RyNsSmDAT!panJ?giWEKBC)v8N(W02L;Vo=^7IbBh9eS*t zM?d3r{RA^CozUZA#-hcl9;rIS(|~Sx`p}Otr-u(gIDga`(*L$pIf19-jOoT)$eL}I zmFr8^H7XBRY{}7>gZ0K7u3n|bq&k7Re++dT^|cqWzsgQkA10gRJbOqs)KeM1uaxcD ziF~mwuAQ;*;5i=kMrW@|+Ph;V$-It3pNQX!de*xebd;YS)Lo==h{dd(?ZgXu`667E z#sf%$rwzTK{Gc~h%ch8WA62?Q+laVc*wRe7A={6ou!EuN z679o&VZUcvmyZo5Cv-M+IY+O|I|h?;So$P6MV&g^`n=L4C$Hz!zA|n7nYFLq85P@{ zex@>JtUo^(6&ZUmE<@SyekxIapvOd8G)%i>`$wlO`sHA94%042tDZk)lJl5q+YPpU zyXsTnFC)L|_f?;Yv7HzG9tqdTpEh=p{gWIU^fPuDahn>+ln2+@%EOSxUn9-~*8XT7 zxR1qboiBYV*A3)cg2TJ)oi6~c%3+%rSMOs{M<>>}1Z|h2(~G+Cd(2P0XkY3vZfiiF z_FotSzKePFJAl8fJLVq8SXaYXo%8K+bp9*&M%9?9AHLfp-)-P~8~EPd58pBq-v`0> z#V@lxFJ`me7bh{yx1+UP7PxtEi`ilx&Ssc{BAgEw<9NWkPu5joTwcBB^yVM)dFJWO z-AUv1k4@wCk1$^El4HExYTQ9>fEag(@vH@NKiOt%gZ~crDG!tv%10M&59a1?LDsh* z>syd@24sC1vc9cb=e`VCUxJ+bAtUrwydN_5jH7t~+9FjiQsxRbo*Hah zdpzF^Yc8mJ$e(H6u%nh8c#4m)q9d+*;|82JEHjM_Gv>iHaQiWE9{y!a@{pe?50HDP zZQy`;I5;+Wc*ERxt9IO+2aM4NYR3o8!`Rr;v!*=kS9yrC^{uKeLcP{ZebH`HUsOeP zK-R@$sQXFv!Lx^tMMk?WY&je9Bad8uv`K93xH|2EahOkwxyWeCzuF{!qAo-KiF$xB z%Ng6yk+HF%$%Ex#B=z9Pkm~Zjl==3)^!fI{ZR#H~jb~`Cpz6U$%Hj2~$pbp`#5g@s zmyw5I)#Z$JLCh-#sS6`6gMU67@-tbN&3&_{dnj$uh~>Xgj0txz!`WHU%g2-Z)Y`Pc z*bavAY8qrtu_jhCQC#fx|AHlfXAR2;X6jCplj$+9SuQfSbmt|1p;1)Eu*{Lm8(&jqwfo zLp~O+qOmaPkm?q#uR}j--+}TSt!Im4I<-%w{jL@70zcHh1V3KZk{_+Hn)!7l_?^=) zzk$ZlUnLubu9ZFQ$2gnnzFL#tO16f0kCZ3TZyBb33;r|iw+;+x4m;xdI=bWNA2W^k`dd{Ss6#OOnvX}G3k3pcN{%7HZ;29 z=&`BGqdSfsn>?JAadgJI@NZ*M7tYE!I%8WT_CQ9vElP}|W6sVme4Ke4eLdiwLB^%S zT$knJ(ksAMjeF#JZ`%0$Ovcd*C?A8!dnV)PDd1}!o1XbNI{AD?>UyuzHH`%^?n{gX zPfz)XWMIL@)%0r^eu$FMfWrj0^i83oiIp9tzvlg+&z{|`r z_GNarDZhy_Gq3-QsLZ}QCS^wLCZn@}U0I#^AMth*YZ2;f9Kr3KPQX2;c8KFg#eSBc z9p3r_r|EHY{_Vr$b~6*-;k28I?>pezHHf^!X*U($Ux4q(+D)-f)%eVoc|fOhs9h&Q*h2^$`6y8}Dtds}Eb6YXjA>$PZ8$Ha#J zn5iBPHxDe+{@mELoj=T!hvBv*8Oz}@l*13kq#Q=AJ&aO0jB$JD$?p8w$;|EH0l+_SVHf3N5WZ*99^MVUXQMql({sLGM0-3?`&Li=i)kFG z(Y_3gBMsJf4#_o)^KtCnT6UM1Pttgn#*y+|Z@=yNP|x+wGwp3>loK-3-l?)X+Ivjc zia0~jcdnPqDb^p(ww(4%azclRb6vwaV@moQ9XVe&?Jp+uX_j+1`izcVxql~n+bx7^qbK0(9 z&z%p^-u?NM-XMI3IacI+&jH^T&&pZQXEL4z{Rr=FeTcK5Tz0fyyXg#=Y|E<1ul9$r z{~eWnIt%(F{B%x$&I{04fhcaz7B<;D{v664`)9PrF4Nma<0h%YGWcUJ>zxDbr^m3@ zehlwt_4jTT#Ssq+-rbsxcegBfcWXM{-C}rm%fP!^DnC_ft&-YrwEdJ9z84RFd~4pG zc$oFZ-xud_V~52#+*qB?&*8>?$M`wi*jsRM#x?df-WhvYgWUbUGZw2sd=1_+>*t-a z*vky`{pagA#e)Z>^B&F|O!^@Hz_X^a1&Ou=`Jpi?&yVbz1n)s)8z60ww}E7%ype2- z%XSj>dnc8#v>lR7l{d-OMY&)o%EQZe2Y74No_HN_pON;yQ`x&k*!x4$ z-XD|p{)Ei$%a;D_8TK$>J?7=oKYen!mF~R><>ry?#Qv1MjGrPOGzaB2hW?1+VS9!mJW_hIh>m*57Dz!4)Q(h z(YB>CS#utmEz!EU*smMyJY-yRHkU(&^UFia1KOn{V^bf_WX*YKd7yF-YtExx4ss6; z-(JY+EdO)ndBkkMJ+dFbd~q$Kc}Fy{2Zy=Fnav|6g0Ip?e|(3!He7~tsa&oe$VK@W zMBbs!PpV9O|MaJkt~no-XMq1LX?{ZAmiQ3w+nrS3mXPB|8ryg%9~d*Hj%_@^p|K5} zN1(9{_3JdYIe@&M`Pc?ymqEui1B~_fSbd_mvZkU81J3%m1V@q_K-E zM~X+D6JwjZ5l>?u(gS@*Loa^^z}QygHzquHnj=zJ7T&rv9@OPS=%ux>pxeUhA`qt6FTa%P+dpq(tExvXk4FlX^dKh0%& z$PXNv%k*H5%T|}xX+~)=|HcdZ)=<{%M%)%OXUYTWSYjS9qC9+iO!9DXraZu|hm{A` z&-$tL`7z0Z?QGcf8Yi>f{_ z)CaB9zJU7T0p|20t_K;vDUo3fUdg`SB)eD1-meXbHFz2?nDfB%R4De%qi3OCAL>5B zfO+WGhK96{FyeBM`w073S8iwd`+WS5J%z*>JizUpvk9(jNR0pYna2OXadZxKJgtfG z^gh~0m~ZPLD0aH_~pQ^}^yk@rSTpxJ2XM zr-<#eigm*CHL)&U2{`14U7`WEa8LXm;7*pfB@#DB;uc8U@r0YdC%zfDpUU;eopQY$ z>+lR`hhzT@IKHhII|-Ng|CMCP-4nkVG{2KHC6Wf~o}A{FaA}SHFxEY#tsh(F>ecYQ zHy%bAlgvGHCGkMZyO_3DVT@OZrE_}F8`_X6iB-0`j1d*Yu*x|nltS+FKb z-|C3%lxwC~OXcZ*8*8PvU{3NpTv`*oeULqX+pPnvsbb!6`vCKb8pLDnLFv4Wbl%hT zz4XrCCN8gYPy9;A`;e6PcBL;V?>$o9uS_!{s)^3ptu z8sp_j^`K{OaLt>UzT;2uDI44LprL)THFt z_1@NNLL_aa;l=mRTj1WZ+82PcK{z2_^VOjsg}tpEzEy2)BAwb5E4kUXXYb~>GoT^REoyK7k06*|J8WxJLa!e(>3ve6I(L93TBA5&J zQo!hU9q2M}6HSZ4tI9VXu|BF-@3dU;<{O9kPXG|zM%)qLNHJI`!rO5-0_K9tKzB8; zr@;Fp?(KlLOE~fSr#Ii=yeR$v?$;6D3Y~*)-Xr!$ZI&Aa0`YwZ_Z*aw2QK0ZuLmW` za0+)j;09c}h*u$aYys?P0!Z0gWLm^)9^$RvjK{g%A$}cr5&R0k*8)y@qcoOF**y~e zp@4JQHk)LRB7P3+gwj^&t&s6^0O~^gOvLY_9}TF=U-L-zqggdOox2?O+3&aMzqh>k z#?jv#K9bJ}_aJbe{tjd(L$AtjencgnBh@grH8 zaN84dkuAOe+ylQu9n9sphb)iGee}GVopW~0zVCDQ&(de;N-#td{vUzA@IB~9ra6Wa`#vsne*su%a3^JQ2bKF-}P}k zPWFX(*CWnH9k-ZlkgE~psRu|by1n?^We^>$G&cjW0`Vin-2rl_m@3il-)!b*j zUtjTnFW<&)$zi2U!@-!<@e4g6gLf7ig!G;ql2;)q?+Mfb?B z7U@zKL)Q+wi@WMKc@B6)cp`_=@26F9-((qfN|$~Vg02%Xp85~ERJ`gVHdbP z50d+e#YGOIu9vQLRu^~GZx@}gh%j~ebZr+7|J^V0^6?1Vb0l0j=r;KEp8VY=>f-2H zBr{I^6kY1Kknr0Z{90#oaaY0T$gs)>^<#8V_f3~d|FgKrk5l5uWmxI?gbcqU^CzfB z@2P&DZm<;g$?_g;H&u?6H8qzSbMWhM=Na?oRV=7bdZlrUC@Z1y9*2vQu1#ei!(?X` zR)MD~p=3l6{}-5F=J?f|em=}k#FxtYq3lD|heF9#)dy8yl2a4oFbk_o@Y~^baTI0$ zneo2?a~J7%N&JUX5oK8DXEV%G;Jak~yrUodrGQ)5WSFbuFUwnmFdmciDxAt@E~h7` zlbf3acj{RkxeU~FF3VpfS(&jSyJ@paa%O!IS5)Tj&^dajthWcaXMy` zquIv;sIP!u``q|*3Eg7*4jlbkcxZE`%q0I$fuo&QdNcf1s|~*($MoAMdhWRM;aHru zP2_0Ksl@A5JS>w++yLn-!B?M9;v)YZdQ2>>BZt(cPbv+Oa~uzAS@AwNwp{CPty!nx zv(v=Z`nom$1q7JAnnG`gkk$Syh29h)Cv%*SM#uV=ReuGT$QM3MPa;JqRA@Z{)mSvk z*Fj<_bkHDDYf%6LDkNi{a$l3HSzh zau>jp$MT#6%_m5~?}43-ALId$p859>a2c3q-_L>c%%@3L!R>_k3$7&=1)OH;YD~%acG)z3p{rEkt~O<37+;3C;_V`nA*QaA)A&@rDCfFx{@Nw3jP=TKs!vK&Baf`UsUM$t?h3B7gHu2 zuV-^VS(@XGoNN?8@kv5{GiMU~EayQy2+D1;faMSiis4}g%b^0KV&h?*Io%*GbiC#y z3&}c#NXJ`Q2e}YARQs<}s18FG&VJE(|-Xe4U@wK5;axEnFK_d*0xU20$P zE1;-0O*WIN(KNRzDtV`BU`6{Un^f71s#dqqb|+GjEs(`x4N%CcH*v?hl^myj3wNyl zhnzzF267DjARODLcxW9?Emc(QVKNMRy|0;~$K8O;0+U~MU!aj`8=M6MtipX6Zbyt5 zZE@;TNDUOjA1rH^+l2r&0Rhj}*61g-HQCy=aIia(Lqv*@y#XvMDj`6e?tdUe`$Es-w%tgu z865Tw!pCvjn+P^@JmF>OhuSH>z`UKHvkHCze+e>HfSWm-Kf%+PC5qJH{2fABqUf@Z zz|S5A7JfO7XYegB$lZ$vnNez={~(M=+KK)sa4f$XzXE91g?Om`HIw1kT7f{f9l}r- z==>@kS^RM?`RDdSWg0RAIOwYeGXGzZDoK+>znvB87%vPf1-42@>Q4U_}I3l7Mq2g6z*RN+L(oR+SJ!ZW+Rrh{!|B%~Q|6gkuzxAgQI8 z{1qm6N+F8I3z=jR#pWbnvNR78BR!=U=B^C2%|%oggr=M ztWrQ;lB6P=S!)u>o&*DuLzSxYa}Xn|&*Y>Xn2RDISszxaVTz)#DdVx1foWe7=V-IJ ziqIUBjb-;0K#o~1(hdxd)TDB0%0Db|0L|oQ&rsLUE#G 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_8_16(r0,r1,r2) do /* mul */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xd8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x27 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MUL_RRR_I_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0x4d8 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MUL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genMult(h2_insn_t * ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 9, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0301, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genMUL_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res; + pifi fPtr; + + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 & in2 + in1 = atoi (argv[2]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + printf("// Compilette for simple addition between 1 variable with\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = (pifi) genMult (ptr, in0); // Generate instructions + res = fPtr(in1); // Call generated code + printf("%d * %d = %d\n", in0, in1, res); + if (res == (in0 * in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Mult-With-Specialization.power b/CodeExamples/Mult-With-Specialization.power new file mode 100755 index 0000000000000000000000000000000000000000..7187df068ab3f7f066a0debe97737838454486b6 GIT binary patch literal 78208 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 T3hDFjey@ +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_POWER +#define H2_POWER + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +typedef uint32_t h2_insn_t; +static h2_insn_t *h2_asm_pc; +static h2_insn_t *h2_save_asm_pc; + +static ticks_t h2_getticks(void) +{ + unsigned int tbl, tbu0, tbu1; + + do { + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu0)); + __asm__ __volatile__ ("mftb %0" : "=r"(tbl)); + __asm__ __volatile__ ("mftbu %0" : "=r"(tbu1)); + } while (tbu0 != tbu1); + + return (((unsigned long long)tbu0) << 32) | tbl; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + +#endif /*H2_POWER*/ +/* In memory instruction generator */ +#define power_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define P1_BLR__I_32_1() do /* ret */ { power_G32(((0x4e800020 >> 0) & 0xffffffff)); \ + } while(0); +#define V2_03_VADDSBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x300 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUBS_RRR_I_8_16(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x200 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDSHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x340 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUHS_RRR_I_16_8(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x240 & 0x7ff) >> 0)); } while(0); +#define V2_03_VADDUWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x280 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_32_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VADDSWS_RRR_I_32_4(r0,r1,r2) do /* add */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x380 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x214 & 0x7ff) >> 0)); } while(0); +#define P1_ADDI_RRI_I_64_1(r0,r1,i0) do /* add */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_SUBI_RRI_I_32_1(r0,r1,i0) do /* sub */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|(((-i0) & 0xffff) >> 0)); } while(0); +#define PPC_SUB_RRR_I_32_1(r0,r2,r1) do /* sub */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x50 & 0x7ff) >> 0)); } while(0); +#define P1_LBZ_RRI_I_8_1(r0,r1,i0) do /* r */ { power_G32(((0x22 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LBZX_RRR_I_8_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0xae & 0x7ff) >> 0)); } while(0); +#define P1_LHZ_RRI_I_16_1(r0,r1,i0) do /* r */ { power_G32(((0x28 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZ_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x20 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZU_RRI_I_32_1(r0,r1,i0) do /* r */ { power_G32(((0x21 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LWZUX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6e & 0x7ff) >> 0)); } while(0); +#define P1_LWZX_RRR_I_32_1(r0,r1,r2) do /* r */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2e & 0x7ff) >> 0)); } while(0); +#define P1_STB_RRI_I_8_1(r1,r0,i0) do /* w */ { power_G32(((0x26 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STBX_RRR_I_8_1(r1,r0,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1ae & 0x7ff) >> 0)); } while(0); +#define P1_STH_RRI_I_16_1(r1,r0,i0) do /* w */ { power_G32(((0x2c & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STW_RRI_I_32_1(r1,r0,i0) do /* w */ { power_G32(((0x24 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_STWX_RRR_I_32_1(r0,r1,r2) do /* w */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x12e & 0x7ff) >> 0)); } while(0); +#define PPC_STD_RRI_I_64_1(r1,r0,i0) do /* w */ { power_G32(((0x3e & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0x3fff) << 2)|((0x0 & 0x3) >> 0)); } while(0); +#define P1_MULLW_RRR_I_32_1(r0,r1,r2) do /* mul */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1d6 & 0x7ff) >> 0)); } while(0); +#define P1_MULLI_RRI_I_64_1(r0,r1,i0) do /* mul */ { power_G32(((0x7 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_32_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define P1_MV_RR_I_32_1(r0,r1) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((0x0 & 0xffff) >> 0)); } while(0); +#define P1_LI_RI_I_64_1(r0,i0) do /* mv */ { power_G32(((0xe & 0x3f) << 26)|((r0 & 0x1f) << 21)|((0x0 & 0x1f) << 16)|((i0 & 0xffff) >> 0)); } while(0); +#define V2_03_VSLB_RRR_I_8_16(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x104 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLH_RRR_I_16_8(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x144 & 0x7ff) >> 0)); } while(0); +#define P1_SLW_RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x30 & 0x7ff) >> 0)); } while(0); +#define P1_SLW__RRR_I_32_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x31 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSLW_RRR_I_32_4(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x184 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD_RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x36 & 0x7ff) >> 0)); } while(0); +#define PPC_SLD__RRR_I_64_1(r1,r0,r2) do /* sl */ { power_G32(((0x1f & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x37 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSLD_RRR_I_64_2(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x5c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSL_RRR_I_128_1(r0,r1,r2) do /* sl */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x1c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRB_RRR_I_8_16(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x204 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRH_RRR_I_16_8(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x244 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSRW_RRR_I_32_4(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x284 & 0x7ff) >> 0)); } while(0); +#define V2_07_VSRD_RRR_I_64_2(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x6c4 & 0x7ff) >> 0)); } while(0); +#define V2_03_VSR_RRR_I_128_1(r0,r1,r2) do /* sr */ { power_G32(((0x4 & 0x3f) << 26)|((r0 & 0x1f) << 21)|((r1 & 0x1f) << 16)|((r2 & 0x1f) << 11)|((0x2c4 & 0x7ff) >> 0)); } while(0); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genRET_0(); +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t power_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LBZ_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LBZX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LHZ_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZ_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_LWZU_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZUX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_LWZX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUBS_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUHS_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDUWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VADDSWS_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_ADDI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/power + +P1_BLR__I_32_1(); + +} +h2_sValue_t power_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (power)\\n"); + #endif + // MV const in tmp register + P1 = power_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STBX_RRR_I_8_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_STW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_STWX_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + PPC_STD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_SLW__RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSLW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SLD__RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSLD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSL_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +// No specific optimisation for MUL/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + P1_MULLW_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_MULLI_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRH_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSRW_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_07_VSRD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 128) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + V2_03_VSR_RRR_I_128_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + P1_SUBI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + PPC_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t power_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/power + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + P1_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + P1_LI_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genMult(h2_insn_t * ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 3, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 14, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x780F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = power_genMUL_3(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = power_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + power_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res; + pifi fPtr; + + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 & in2 + in1 = atoi (argv[2]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + printf("// Compilette for simple addition between 1 variable with\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = (pifi) genMult (ptr, in0); // Generate instructions + res = fPtr(in1); // Call generated code + printf("%d * %d = %d\n", in0, in1, res); + if (res == (in0 * in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Mult-With-Specialization.riscv b/CodeExamples/Mult-With-Specialization.riscv new file mode 100755 index 0000000000000000000000000000000000000000..2a6a6a009ea4c5d988f3105be86fe46647641d81 GIT binary patch literal 29172 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%0Ad;3I` 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 RDiVyB@N33KYlT60{||Fa8chHI literal 0 HcmV?d00001 diff --git a/CodeExamples/Mult-With-Specialization.riscv.c b/CodeExamples/Mult-With-Specialization.riscv.c new file mode 100644 index 0000000..b6a8bc2 --- /dev/null +++ b/CodeExamples/Mult-With-Specialization.riscv.c @@ -0,0 +1,755 @@ +/* Begin Header autogenerated part */ +#ifndef H2_COMMON +#define H2_COMMON +/* Common HybroGen inserted code */ +#include +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_RISCV_RV32G +#define H2_RISCV_RV32G + +#define H2SYS /* Has operating system */ + +#include +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +static int h2_riscvVectorLen = 1; +static int h2_riscvVectorWidth = 1; +static h2_sValue_t SP= {H2REGISTER, 'i', 1, 32, 2, 0}; + +#if 0 +/* +https://stackoverflow.com/questions/52187221/how-to-calculate-the-no-of-clock-cycles-in-riscv-clang +*/ + +ticks_t h2_getticks(void) +{ + unsigned long dst; + // output into any register, likely a0 + // regular instruction: + asm volatile ("csrrs %0, 0xc00, x0" : "=r" (dst) ); + // regular instruction with symbolic csr and register names + // asm volatile ("csrrs %0, cycle, zero" : "=r" (dst) ); + // pseudo-instruction: + // asm volatile ("csrr %0, cycle" : "=r" (dst) ); + // pseudo-instruction: + //asm volatile ("rdcycle %0" : "=r" (dst) ); + return dst; +} +#endif + +#if 1 +// From https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h +// HW counter measument +ticks_t h2_getticks(void) +{ + uint64_t result; +#if __riscv_xlen == 64 + asm volatile("rdtime %0" : "=r" (result)); +#elif __riscv_xlen == 32 + uint32_t l, h, h2; + do + { + asm volatile( + "rdtimeh %0 \n" + "rdtime %1 \n" + "rdtimeh %2 \n" + : "=r" (h), "=r" (l), "=r" (h2)); + } while (h2 != h); + result =(((uint64_t)h)<<32) | ((uint64_t)l); +#endif + return result; +} +#endif + + +#if 0 +// System level clock measurment +#include +ticks_t h2_getticks(void) +{ + int res; + struct timeval My_time; + uint64_t tick; + res = gettimeofday(&My_time, NULL); + tick = My_time.tv_sec * 1000000 + My_time.tv_usec; + if (0 == res) + { + return tick; + } else + { + return 0; + } +} +#endif + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + long pageSize= getpagesize(); + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%u insns generated in %lld ticks. %lld ticks / insn\n", (unsigned int)h2_insnGenerated, (long long) h2_codeGenTime, (long long) h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + perror("(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /*H2_RISCV_RV32G*/ +/* In memory instruction generator */ +#define riscv_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define RV32I_RET__I_32_1() do /* RET */ { riscv_G32(((0x8067 >> 0) & 0xffffffff)); \ + } while(0); +#define RV32I_ADDI_RRI_I_32_1(r1,r0,i0) do /* ADD */ { riscv_G32(((i0 & 0xfff) << 20)|((r0 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r1 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_ADD_RRR_I_32_1(r3,r1,r2) do /* ADD */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SUB_RRR_I_32_1(r3,r1,r2) do /* SUB */ { riscv_G32(((0x20 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SRLI_RRI_I_32_1(r3,r1,i0) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SRL_RRR_I_32_1(r3,r1,r2) do /* SR */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x5 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_SLLI_RRI_I_32_1(r3,r1,i0) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((i0 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SLL_RRR_I_32_1(r3,r1,r2) do /* SL */ { riscv_G32(((0x0 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32M_MUL_RRR_I_32_1(r3,r1,r2) do /* MUL */ { riscv_G32(((0x1 & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x33 & 0x7f) >> 0)); } while(0); +#define RV32I_LB_RRI_I_8_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LH_RRI_I_16_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_LW_RRI_I_32_1(r3,r1,i1) do /* R */ { riscv_G32(((i1 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((r3 & 0x1f) << 7)|((0x3 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RR_I_32_1(r0,r1) do /* MV */ { riscv_G32(((0x0 & 0xfff) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((r0 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_MV_RI_I_32_1(r3,i1) do /* MV */ { riscv_G32(((i1 & 0xfff) << 20)|((0x6 & 0xff) << 12)|((r3 & 0x1f) << 7)|((0x13 & 0x7f) >> 0)); } while(0); +#define RV32I_SB_RRI_I_8_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x0 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SH_RRI_I_16_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x1 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +#define RV32I_SW_RRI_I_32_1(r1,r2,i1) do /* W */ { riscv_G32((((i1 >> 5) & 0x7f) << 25)|((r2 & 0x1f) << 20)|((r1 & 0x1f) << 15)|((0x2 & 0x7) << 12)|((i1 & 0x1f) << 7)|((0x23 & 0x7f) >> 0)); } while(0); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3); +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genRET_0(); +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1); +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t riscv_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (riscv)\\n"); + #endif + // MV const in tmp register + P1 = riscv_genMV_2(PTMP, P1); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genMUL_4(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2,h2_sValue_t P3) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul & 1 mv +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (riscv)\n"); +#endif + return riscv_genMV_2(P0, immValueZero); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (riscv)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return riscv_genSL_3(P0, P1, P2); + } + +if (isValue(P2)) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (riscv)\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32M_MUL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_LW_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_ADDI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SRLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SRL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/riscv + +RV32I_RET__I_32_1(); + +} +h2_sValue_t riscv_genMV_2(h2_sValue_t P0,h2_sValue_t P1) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + RV32I_MV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + RV32I_MV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +/* -*- c -*- */ +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI sub (riscv)\\n"); + #endif + P2 = riscv_genMV_2(PTMP, P2); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t riscv_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/riscv + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + RV32I_SLLI_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + RV32I_SLL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +typedef int (*pifi)(int); + +h2_insn_t * genMult(h2_insn_t * ptr, int b) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'i', 1, 32, 10, true}; + h2_sValue_t r = {H2REGISTER, 'i', 1, 32, 5, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'i', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0x73F, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + riscv_genADD_3(SP, SP, intsValue(-48)); +riscv_genW_3(SP, intReg32sValue(18), intsValue(44)); +riscv_genW_3(SP, intReg32sValue(19), intsValue(40)); +riscv_genW_3(SP, intReg32sValue(20), intsValue(36)); +riscv_genW_3(SP, intReg32sValue(21), intsValue(32)); +riscv_genW_3(SP, intReg32sValue(22), intsValue(28)); +riscv_genW_3(SP, intReg32sValue(23), intsValue(24)); +riscv_genW_3(SP, intReg32sValue(24), intsValue(20)); +riscv_genW_3(SP, intReg32sValue(25), intsValue(16)); +riscv_genW_3(SP, intReg32sValue(26), intsValue(12)); +riscv_genW_3(SP, intReg32sValue(27), intsValue(8)); + r = riscv_genMUL_4(r, a, (h2_sValue_t) {H2VALUE, 'i', 1, 32, 0, (int)((b))}, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = riscv_genMV_2(h2_outputVarName, r); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + riscv_genR_3(intReg32sValue(18), SP, intsValue(44)); + riscv_genR_3(intReg32sValue(19), SP, intsValue(40)); + riscv_genR_3(intReg32sValue(20), SP, intsValue(36)); + riscv_genR_3(intReg32sValue(21), SP, intsValue(32)); + riscv_genR_3(intReg32sValue(22), SP, intsValue(28)); + riscv_genR_3(intReg32sValue(23), SP, intsValue(24)); + riscv_genR_3(intReg32sValue(24), SP, intsValue(20)); + riscv_genR_3(intReg32sValue(25), SP, intsValue(16)); + riscv_genR_3(intReg32sValue(26), SP, intsValue(12)); + riscv_genR_3(intReg32sValue(27), SP, intsValue(8)); + riscv_genADD_3(SP, SP, intsValue(48)); + riscv_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *) ptr; +} + + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + int in0, in1, res; + pifi fPtr; + + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + in0 = atoi (argv[1]); // Get the users values in1 & in2 + in1 = atoi (argv[2]); + ptr = h2_malloc (1024); // Allocate memory for 1024 instructions + printf("// Compilette for simple addition between 1 variable with\n"); + printf("// code specialization on value = %d\n", in0); + fPtr = (pifi) genMult (ptr, in0); // Generate instructions + res = fPtr(in1); // Call generated code + printf("%d * %d = %d\n", in0, in1, res); + if (res == (in0 * in1)) + return 0; + else + return -1; +} diff --git a/CodeExamples/Multiple-flt.aarch64 b/CodeExamples/Multiple-flt.aarch64 new file mode 100755 index 0000000000000000000000000000000000000000..5bfdddaab4100ce20e88d390e8ccda8490a3f8b6 GIT binary patch literal 52288 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 +#include +#include +#include +#include + +bool h2_codeGenerationOK; // Does code generation fail ? +typedef int32_t h2_regSet_t; // Register set (signed, use -1 when not allocated) +static uint32_t h2_insnGenerated; +typedef unsigned long long ticks_t; +static ticks_t h2_codeGenTime; + +typedef enum { H2REGISTER, H2VALUE, } VALORREG; +typedef struct +{ + int ValOrReg; // is H2REGISTER or immediate VALUE ? + char arith; // int, flt or other arithmetic + int vLen; // vector len + int wLen; // word len + int regNro; // register number (if register) + int valueImm; // immediate value (if not register) + bool dontFree; // if register, don't free +} h2_sValue_t; +#define sValueDef(VALUE, ARITH, VECTORLEN, WORDLEN, REGNO, IMMVAL) ((h2_sValue_t){.ValOrReg = VALUE, .arith = ARITH, .vLen = VECTORLEN, .wLen = WORDLEN, .regNro = REGNO, .valueImm = IMMVAL}) +#define intsValue(V) sValueDef(H2VALUE, 'i', 1, 32, -1, V) +#define intReg32sValue(R) sValueDef(H2REGISTER, 'i', 1, 32, R, 0) +#define immValueZero intsValue(0) +// Usefull macro instruction to simplify instruction selector code +#define isInt64_1(P) ((P.arith == 'i') && (P.wLen <= 64) && (P.vLen == 1)) +#define isInt32_1(P) ((P.arith == 'i') && (P.wLen <= 32) && (P.vLen == 1)) +#define isInt0(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (0 == P.valueImm)) +#define isInt1(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE) && (1 == P.valueImm)) +#define isValue(P) ((P.arith == 'i') && (P.ValOrReg == H2VALUE)) +#define isReg32(P, X) ((P.arith == 'i') && (P.ValOrReg == H2REGISTER) && (X == P.regNro)) +#define isRRR(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) +#define isRRV(P0, P1, P2) (P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + + +typedef union { + float f; + unsigned long i; +} h2_float_int_u; + +static int h2_log2(int value) +{ // integer logarithm + int log = 0; + while (value >>= 1) { ++log; } + return log; +} +// Print register map : F for free register, . for allocated +void printRev (int value, int pos) +{ // Print a bitset in reversal order (recursive) + if (pos != 0) + printRev (value >> 1, pos - 1); + printf ("%1c", (value % 2)?'.':'F'); +} + +// Dynamic register allocation handling +// h2_regSet mask : 0 mean free register, 1 register set +// 3 2 1 Bit position = reg Number +// 1098 7654 3210 9876 5432 1098 7654 3210 +// 1111 1111 1111 1111 0000 0001 0011 1111 +typedef struct +{ // Register allocation sets for + // int, float, vector of ints, vector of floats + int intSet, fltSet, vintSet, vfltSet ; +} h2_RegSets_t; + +h2_RegSets_t h2_regSet, h2_regSetInit; + +// Print integer register set +void printRegState(char * msg, int regNo, int registerSet) +{ + int count = 8 * sizeof (registerSet) - 1; + h2_regSet_t tmpReg = registerSet; + printf ("%02d : Reg %s\n", regNo, msg); + for (int i = count; i >= 0; i--) // Tens + (0 == (i % 10))?printf ("%d", i/10):printf (" "); + printf ("\n"); + for (int i = count; i >= 0; i--) // Unit + printf ("%d", i%10); + printf ("\n"); + printRev (tmpReg, count); // Bit set + printf ("\n"); +} + +// Initialize registers sets allocation +static void h2_initRegisterMasks(int intmask, int fltmask, int vectorintmask, int vectorfltmask) +{ // See H2SymbolTable & H2RegisterBank + h2_regSetInit = (h2_RegSets_t){intmask, fltmask, vectorintmask, vectorfltmask}; +} + +static void h2_resetRegisterMasks() // Reset register set from initializers +{ + h2_regSet = h2_regSetInit; +#ifdef H2_DEBUG_REGISTER + printRegState("RESET", -1, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER +} +int h2_getReg () // Get new register +{ + /* Search for the 1st free register */ + h2_regSet_t tmpReg = h2_regSet.intSet; + for (int i = 0; i < 8 * sizeof (h2_regSet.intSet); i++) + { + if (tmpReg % 2 == 0) + { /* Free register found */ + h2_regSet.intSet = h2_regSet.intSet | (1 << i); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("GET", i, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + return i; + } + tmpReg >>= 1; + } + printf ("Register allocation failed\n"); + h2_codeGenerationOK = false; + return -1; +} + +// h2_regSet_t regToBeFreed[32]; + +void h2_freeReg (h2_regSet_t v) // Free a register +{ +#if 1 // TODO : To be rethinked + // Is the register freeable ? + int isOK = (h2_regSetInit.intSet >> v) & 1; + if (0 == isOK) + { + h2_regSet.intSet = h2_regSet.intSet & ~(1 << v); /* Update regSet */ +#ifdef H2_DEBUG_REGISTER + printRegState("FREE", v, h2_regSet.intSet); +#endif // H2_DEBUG_REGISTER + } +#endif +} +#endif /*H2_COMMON*/ +#ifndef H2_AARCH64 +#define H2_AARCH64 + +#define H2SYS /* Has operating system */ + +#ifdef H2SYS +#include +#endif + +typedef uint32_t h2_insn_t; /* Instruction size */ +static h2_insn_t *h2_asm_pc; /* PC for code generation */ +static h2_insn_t *h2_save_asm_pc; +#define H2Aarch64SP (h2_sValue_t) {REGISTER, 'i', 1, 32, 31, 0} +/* aarch64 / power examples : + https://github.com/FFTW/fftw3/blob/master/kernel/cycle.h */ + +static inline ticks_t h2_getticks(void) +{ + uint64_t Rt; + asm volatile("mrs %0, CNTVCT_EL0" : "=r" (Rt)); + return Rt; +} + +static void h2_iflush(void *addr, void *last) +{ + h2_insnGenerated = (last-addr)/sizeof (h2_insn_t); +#ifdef H2SYS + __clear_cache((char *)addr, (char *)last); // Flush data cache where binary code were written + long pageSize= getpagesize(); // Make the page executable + void *ptmp= (char *)((long)addr & ~(pageSize - 1)); + if (mprotect(ptmp, (last - addr), PROT_READ | PROT_WRITE | PROT_EXEC)) + { + perror("iflush: mprotect"); + exit(-1); + } + /* Gcc function to clear data cache after code generation */ + __clear_cache((char *)addr, (char *)last); +#endif +#ifdef H2_DEBUG + printf ("Flush data cache from %p to %p\n", addr, last); + printf ("%ld insn generated in %ld ticks. %ld ticks / insn\n", h2_insnGenerated, h2_codeGenTime, h2_codeGenTime/h2_insnGenerated); +#endif + if (!h2_codeGenerationOK) + { + fprintf (stderr, "(iflush) Failed code generation\n"); + exit(-5); + } +} + +static h2_insn_t *h2_malloc (size_t size) +{ + return malloc (size); +} + + +#endif /* H2_AARCH64 */ +/* In memory instruction generator */ +#define aarch64_G32(INSN){ *(h2_asm_pc++) = (INSN);} + +/* Single instruction binary code generator*/ +#define A64_RET__I_64_1() do /* ret */ { aarch64_G32(((0xd65f03c0 >> 0) & 0xffffffff)); \ + } while(0); +#define A64_ADD_RRR_I_8_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_8_16(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x73 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_32_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x44 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x58 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_I_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0x458 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRI_I_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_8_16(r0,r1,r2) do /* sub */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x173 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x258 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_32_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x144 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x175 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x375 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x377 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x21 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRI_I_64_1(r0,r1,i0) do /* sub */ { aarch64_G32(((0x344 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_SUB_RRR_I_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0x658 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x0 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_8_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RRR_I_16_8(r0,r1,r2) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MV_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r1 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x44000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_I_32_2(r0,i0) do /* mv */ { aarch64_G32(((0x1e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x1 & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_4(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_32_1(r0,i0) do /* mv */ { aarch64_G32(((0x294 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x138207 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x178101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_32_2(r0,r1) do /* mv */ { aarch64_G32(((0x38101 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x244000 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOV_RI_I_64_1(r0,i0) do /* mv */ { aarch64_G32(((0x694 & 0x7ff) << 21)|((i0 & 0xffff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x178201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_DUP_RR_I_64_2(r0,r1) do /* mv */ { aarch64_G32(((0x138201 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_8(r0,r1) do /* w */ { aarch64_G32(((0x3001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_8_16(r0,r1) do /* w */ { aarch64_G32(((0x13001c & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRB_RRI_I_8_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x1c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_8(r0,r1) do /* w */ { aarch64_G32(((0x13001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_16_4(r0,r1) do /* w */ { aarch64_G32(((0x3001d & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STRH_RRI_I_16_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x3c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_32_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x5c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x5c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_32_2(r0,r1,i0) do /* w */ { aarch64_G32(((0x7e0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x0 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_32_4(r0,r1) do /* w */ { aarch64_G32(((0x13001e & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRR_I_64_1(r0,r1,r2) do /* w */ { aarch64_G32(((0x7c1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ST1_RR_I_64_2(r0,r1) do /* w */ { aarch64_G32(((0x3001f & 0x3fffff) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_STR_RRI_I_64_1(r0,r1,i0) do /* w */ { aarch64_G32(((0x7c0 & 0x7ff) << 21)|((i0 & 0x1ff) << 12)|((0x1 & 0x3) << 10)|((r0 & 0x1f) << 5)|((r1 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_16_8(r0,r1,r2) do /* sub */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_16_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_32_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xe & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_32_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x75 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_32_4(r0,r1,r2) do /* sub */ { aarch64_G32(((0x275 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_64_2(r0,r1,r2) do /* sub */ { aarch64_G32(((0x277 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FSUB_RRR_F_64_1(r0,r1,r2) do /* sub */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xe & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_16(r0,r1) do /* r */ { aarch64_G32(((0x13101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRB_RRI_I_8_1(r0,r1,i0) do /* r */ { aarch64_G32(((0xe5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_8_8(r0,r1) do /* r */ { aarch64_G32(((0x3101c & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_4(r0,r1) do /* r */ { aarch64_G32(((0x3101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDRH_RRI_I_16_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x1e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_16_8(r0,r1) do /* r */ { aarch64_G32(((0x13101d & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRI_I_32_1(r0,r1,i0) do /* r */ { aarch64_G32(((0x2e5 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDP_RRI_I_32_2(r0,r1,i0) do /* r */ { aarch64_G32(((0xb3 & 0x3ff) << 22)|((i0 & 0x7f) << 15)|((0x0 & 0x1f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_2(r0,r1) do /* r */ { aarch64_G32(((0x3101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_32_4(r0,r1) do /* r */ { aarch64_G32(((0x13101e & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LDR_RRR_I_64_1(r0,r1,r2) do /* r */ { aarch64_G32(((0x7e3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x36 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LD1_RR_I_64_2(r0,r1) do /* r */ { aarch64_G32(((0x13101f & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_16_8(r0,r1,r2) do /* mul */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_16_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x7 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_32_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x2 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_32_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x37 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_32_4(r0,r1,r2) do /* mul */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x37 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_64_2(r0,r1,r2) do /* mul */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x37 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMUL_RRR_F_64_1(r0,r1,r2) do /* mul */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x2 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RR_F_32_1(r0,r1) do /* mv */ { aarch64_G32(((0x78810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RI_F_32_1(r0,i0) do /* mv */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_MOVI_RI_F_32_4(r0,i0) do /* mv */ { aarch64_G32(((0x9e0 & 0x1fff) << 19)|(((i0 >> 5) & 0x7) << 16)|((0x3d & 0x3f) << 10)|((i0 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RR_F_64_1(r0,r1) do /* mv */ { aarch64_G32(((0x79810 & 0x3fffff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FMOV_RI_F_64_1(r0,i0) do /* mv */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((i0 & 0xff) << 13)|((0x80 & 0xff) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_16_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x72 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_16_8(r0,r1,r2) do /* add */ { aarch64_G32(((0x272 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x5 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_32_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x71 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_32_4(r0,r1,r2) do /* add */ { aarch64_G32(((0x271 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_ADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_32_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_64_2(r0,r1,r2) do /* add */ { aarch64_G32(((0x273 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x35 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRR_F_64_1(r0,r1,r2) do /* add */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xa & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FADD_RRI_F_64_1(r0,r1,i0) do /* add */ { aarch64_G32(((0x244 & 0x3ff) << 22)|((i0 & 0xfff) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_32_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x1f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_32_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRI_I_64_1(r0,r1,i0) do /* sr */ { aarch64_G32(((0x34c & 0x3ff) << 22)|((i0 & 0x3f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSR_RRR_I_64_1(r0,r1,r2) do /* sr */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x9 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_32_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x14c & 0x3ff) << 22)|((((32 - i0)% 32) & 0x3f) << 16)|(((31 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_32_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0xd6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRI_I_64_1(r0,r1,i0) do /* sl */ { aarch64_G32(((0x34d & 0x3ff) << 22)|((((64 - i0)% 64) & 0x3f) << 16)|(((63 - i0) & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_LSL_RRR_I_64_1(r0,r1,r2) do /* sl */ { aarch64_G32(((0x4d6 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x8 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_16_8(r0,r1,r2) do /* div */ { aarch64_G32(((0x372 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_16_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x172 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0xf & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_32_4(r0,r1,r2) do /* div */ { aarch64_G32(((0x371 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_32_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x171 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_32_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xf1 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x6 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_64_1(r0,r1,r2) do /* div */ { aarch64_G32(((0xf3 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x6 & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +#define A64_FDIV_RRR_F_64_2(r0,r1,r2) do /* div */ { aarch64_G32(((0x373 & 0x7ff) << 21)|((r2 & 0x1f) << 16)|((0x3f & 0x3f) << 10)|((r1 & 0x1f) << 5)|((r0 & 0x1f) >> 0)); } while(0); +h2_sValue_t aarch64_genRET_0(); +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2); +h2_sValue_t aarch64_genRET_0() +{ +// No generic optimisation for RET + +// No specific optimisation for RET/aarch64 + +A64_RET__I_64_1(); + +} +h2_sValue_t aarch64_genMUL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MUL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ + // if 2 operands are constants do multiplication evaluation (Thanks Kilian for the bug report) + if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) + { + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm * P2.valueImm }; + } + /* if (isInt0(P2) || isInt0(P1)) */ + /* { // X * 0 = 0 Avoid 1 operation mul & 1 mv */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *0 P2 (generic)\n"); */ + /* #endif */ + /* return immValueZero; */ + /* } */ + /* if (isInt1(P2)) */ + /* { // X * 1 = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P2 (generic)\n"); */ + /* #endif */ + /* P1.dontFree = true; */ + /* return P1; */ + /* } */ + /* if (isInt1(P1)) */ + /* { // 1 * X = X propagate register result */ + /* #ifdef H2_DEBUG_INSN */ + /* printf ("Optim for *1 P1 (generic)\n"); */ + /* #endif */ + /* P2.dontFree = true; */ + /* return P2; */ + /* } */ + +/* -*- c -*- */ +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +if (isInt0(P2)) + { // X * 0 = 0 Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *0 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, immValueZero, P1); + } + +if (isInt1(P2)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P2 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P1, P1); + } + +if (isInt1(P1)) + { // X * 1 = X Avoid 1 operation mul +#ifdef H2_DEBUG_INSN + printf ("Optim for *1 P1 (aarch64)\n"); +#endif + return aarch64_genMV_3(P0, P2, P2); + } + +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for MUL %d (power of 2) -> sl %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSL_3(P0, P1, P2); + } + +// Mv constant value in register, then do division +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI mul (aarch64)\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); + // No return continue instruction selection +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FMUL_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MUL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SR instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SR + +// No specific optimisation for SR/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SR instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSUB_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SUB instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do substraction evaluation (Thanks Kilian for the bug report) +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm - P2.valueImm }; +} + +// No specific optimisation for SUB/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_SUB_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_SUB_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FSUB_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SUB instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genW_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for W instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for W + +/* -*- c -*- */ + +/* if (isInt32_1(P0) && isInt0(P1) && isInt0(P2) ) */ +/* { */ +/* #ifdef H2_DEBUG_INSN */ +/* // Store const 0 in memory (alias store, r31 interpreted as 0) */ +/* printf ("Store 0 (aarch64)\\n"); */ +/* #endif */ +/* A64_STR_RRI_I_32_1(P0.regNro, 31, 0); */ +/* return P0; */ +/* } */ + +if (isValue(P1)) + { // Store constant (Should use RRI variant) + h2_sValue_t PTMP = {H2REGISTER, P1.arith, P1.vLen, P1.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RI W (aarch64)\n"); + #endif + // MV const in tmp register + P1 = aarch64_genMV_3(PTMP, P1, immValueZero); + // No return continue instruction selection + } + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_8_16(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_8(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_16_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_32_4(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_ST1_RR_I_64_2(P0.regNro, P1.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 8) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 16) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 32) && (P1.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_STR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P1; + } + + if ((P1.arith == 'i') && (P1.wLen <= 64) && (P1.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_STR_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P1; + } + printf ("Warning, W instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genDIV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for DIV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// if 2 operands are constants do division evaluation +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return (h2_sValue_t) {H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm / P2.valueImm }; +} +// Transform RIR in RRI : P1 & P2 permutation +if ((P1.ValOrReg == H2VALUE) && (P2.ValOrReg == H2REGISTER)) + { + h2_sValue_t PTMP = P2; + P2 = P1; + P1 = PTMP; + } + +/* -*- c -*- */ +// X * NPowerOf2 = X >> N (immediate shift left) +if (isValue(P2) && ((P2.valueImm != 0) && !(P2.valueImm & (P2.valueImm - 1)))) + { + int shiftValue = h2_log2(P2.valueImm); + #ifdef H2_DEBUG_INSN + printf ("Optim for DIV %d (power of 2) -> sr %d (aarch64)\n", P2.valueImm, shiftValue); + #endif + P2.valueImm = shiftValue; // Instruction shift left immediat + return aarch64_genSR_3(P0, P1, P2); + } +if ((P2.ValOrReg == H2VALUE) && (P2.arith == 'i')) +{ + h2_sValue_t PTMP = {H2REGISTER, P2.arith, P2.vLen, P2.wLen, h2_getReg()}; + #ifdef H2_DEBUG_INSN + printf ("Fallback for no RRI div (aarch64)\\n"); + #endif + P2 = aarch64_genMV_3(PTMP, P2, immValueZero); +} + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FDIV_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, DIV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genADD_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for ADD instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +/* -*- c -*- */ +// If 2 operands are constants do addition +if ((P2.ValOrReg == H2VALUE) && (P1.ValOrReg == H2VALUE) && (P1.arith == 'i')&& (P2.arith == 'i')) +{ + return sValueDef(H2VALUE, P1.arith, P1.vLen, P1.wLen, -1, P1.valueImm + P2.valueImm ); +} +if (isInt0 (P2)) + { // P0 = P1 + 0 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P1.regNro); + #endif + P1.dontFree = true; + return P1; + } +if (isInt0 (P1)) + { // P0 = 0 + P2 + #ifdef H2_DEBUG_INSN + printf ("Optim add for 0 (generic) return reg %d\n", P2.regNro); + #endif + P2.dontFree = true; + return P2; + } + +// No specific optimisation for ADD/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_8_16(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_ADD_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_16_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_32_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_32_4(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_ADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_64_2(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_FADD_RRR_F_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_FADD_RRI_F_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + printf ("Warning, ADD instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genSL_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for SL instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for SL + +// No specific optimisation for SL/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_32_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LSL_RRI_I_64_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LSL_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, SL instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 2, (0==P2.ValOrReg)?"REG":"VAL", P2.arith, P2.wLen, P2.vLen, P2.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genR_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for R instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for R + +// No specific optimisation for R/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 16) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_16(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_8_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_16_8(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_LD1_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRB_RRI_I_8_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDRH_RRI_I_16_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDR_RRI_I_32_1(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2VALUE) + { + A64_LDP_RRI_I_32_2(P0.regNro, P1.regNro, P2.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_LDR_RRR_I_64_1(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, R instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} +h2_sValue_t aarch64_genMV_3(h2_sValue_t P0,h2_sValue_t P1,h2_sValue_t P2) +{ +#ifdef H2_DEBUG_INSN + printf ("Start code gen for MV instruction\n"); + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); + printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); + printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm); +#endif // H2_DEBUG_INSN +// No generic optimisation for MV + +// No specific optimisation for MV/aarch64 + + if ((P0.ValOrReg == H2REGISTER) && (P0.regNro == -1)) + P0.regNro = h2_getReg(); + if ((P1.ValOrReg == H2REGISTER) && (P1.regNro == -1)) + P1.regNro = h2_getReg(); + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MV_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_I_32_2(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_4(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 32) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_32_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_MOV_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOV_RI_I_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 64) && (P0.vLen == 2) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_DUP_RR_I_64_2(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_FMOV_RR_F_32_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_FMOV_RI_F_32_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 32) && (P0.vLen == 4) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_MOVI_RI_F_32_4(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER) + { + A64_FMOV_RR_F_64_1(P0.regNro, P1.regNro); + return P0; + } + + if ((P0.arith == 'f') && (P0.wLen <= 64) && (P0.vLen == 1) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2VALUE) + { + A64_FMOV_RI_F_64_1(P0.regNro, P1.valueImm); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 8) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_8_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + + if ((P0.arith == 'i') && (P0.wLen <= 16) && (P0.vLen == 8) && P0.ValOrReg == H2REGISTER && P1.ValOrReg == H2REGISTER && P2.ValOrReg == H2REGISTER) + { + A64_MOV_RRR_I_16_8(P0.regNro, P1.regNro, P2.regNro); + return P0; + } + printf ("Warning, MV instruction generation failed\n"); + h2_codeGenerationOK = false; + printf ("ValOrReg / arith / wLen / vLen / regNro / valueImm\n"); printf ("P%d: %s/%c/%d/%d/%d\n", 0, (0==P0.ValOrReg)?"REG":"VAL", P0.arith, P0.wLen, P0.vLen, P0.valueImm); printf ("P%d: %s/%c/%d/%d/%d\n", 1, (0==P1.ValOrReg)?"REG":"VAL", P1.arith, P1.wLen, P1.vLen, P1.valueImm);return immValueZero; +} + +/* End Header autogenerated part */ +// -*- c -*- +#include +#include + +/* Pointer on function which take 2 floats and return float */ +typedef float (*pifff)(float, float); + +/* C compilette prototype */ +h2_insn_t * genAddf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genADD_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genMulf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genMUL_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genSubf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genSUB_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +h2_insn_t * genDivf(h2_insn_t * ptr) +{ + /* Code Generation of 3 instructions */ + /* Symbol table :*/ + /*VarName = {ValOrLen, arith, vectorLen, wordLen, regNo, ValueImm, dontFree} */ + h2_sValue_t a = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t b = {H2REGISTER, 'f', 1, 32, 1, true}; + h2_sValue_t h2_outputVarName = {H2REGISTER, 'f', 1, 32, 0, true}; + h2_sValue_t r = {H2REGISTER, 'f', 1, 32, 12, true}; + h2_sValue_t tmp0000 = {H2REGISTER, 'f', 1, 32, -1, false}; + + /* Label table :*/ +/* No label table to avoid C warning for empty table ... */ + h2_asm_pc = (h2_insn_t *) ptr; + h2_codeGenerationOK = true; + h2_codeGenTime = h2_getticks(); + h2_initRegisterMasks(0xFFFF0100, 0, 0, 0); + h2_resetRegisterMasks(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask initialization\n"); + #endif // H2_DEBUG_REGISTER + + r = aarch64_genDIV_3(r, a, b); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + h2_outputVarName = aarch64_genMV_3(h2_outputVarName, r, immValueZero); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + aarch64_genRET_0(); + #ifdef H2_DEBUG_REGISTER + printf("Tmp registers mask reset\n"); + #endif // H2_DEBUG_REGISTER + h2_resetRegisterMasks(); + /* Call back code for loops */ + h2_save_asm_pc = h2_asm_pc; + h2_asm_pc = h2_save_asm_pc; + h2_codeGenTime = h2_getticks() - h2_codeGenTime; + h2_iflush(ptr, h2_asm_pc); + + return (h2_insn_t *)ptr; +} + +int main(int argc, char * argv[]) +{ + h2_insn_t * ptr; + float fin0, fin1, fres; + pifff fPtrf; + int resultOK; + + if (argc < 3) + { + printf("Give 2 values\n"); + exit(-1); + } + resultOK = 0; + fin0 = atof (argv[1]); // Get the users values in1 & in2 (flt) + fin1 = atof (argv[2]); + + ptr = h2_malloc (1024); + fPtrf = (pifff) genAddf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple addition of 2 floating point values:\n"); + printf("%f + %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 + fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genSubf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple subraction of 2 floating point values:\n"); + printf("%f - %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 - fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genMulf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple multiplication of 2 floating point values:\n"); + printf("%f * %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 * fin1)) + resultOK += 1; + + ptr = h2_malloc (1024); + fPtrf = (pifff) genDivf (ptr); + fres = fPtrf(fin0, fin1); + printf ("Simple division of 2 floating point values:\n"); + printf("%f / %f = %f\n", fin0, fin1, fres); + if (fres != (fin0 / fin1)) + resultOK += 1; + + if (resultOK == 0) + return 0; + else + return -1; +} diff --git a/CodeExamples/Multiple-flt.power b/CodeExamples/Multiple-flt.power new file mode 100755 index 0000000000000000000000000000000000000000..04c082a1413fd1a7d626f8f33069e7adbadf9924 GIT binary patch literal 78456 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